Java的TCP网络编程
服务端代码:
package socket; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; /** * 聊天室服务端 * @author 小明 * */ public class Server { /** * 运行在服务端的ServerSocket主要有两个作用: * 1:向系统申请服务端口,客户端就是通过这个端口与服务端建立连接的。 * 2:监听服务端口,一旦客户端与服务端建立连接,就会 * 自动创建一个Socket,并通过该Socket与建立连接的 * 客户端进行交互。 * */ private ServerSocket server; public Server() { try{ /** * 实例化ServerSocket的同时要指定向系统申请的服务端口。注意,该端口 * 不能与当前系统其它应用程序申请的端口号一致, * 否则会抛出端口被占用的异常。 */ System.out.println("正在启动服务端..."); server = new ServerSocket(8088); System.out.println("服务端启动完毕!"); }catch(Exception e){ } } public void start() { try { System.out.println("等待客户端连接"); Socket socket = server.accept(); /** * 准备接受客户端连接 * * 这是一个阻塞方法。 *一旦调用accpet()方法,服务端阻塞在这里,等着客户端连接了。 *这时当我们启动客户端时,客户端实例化socket,通过IP找到应用程序。 *这时accpet()马上就会有反应。accpet()方法执行完就返回一个socket。 *通过这个socket就可以与刚建立连接的这个客户端进行通讯了。 *客户端创建一个socket,服务端通过accept()接收一个socket。 *这时候就可以进行沟通了。 * 需要处理异常。 */ InputStream in = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(in); BufferedReader br = new BufferedReader(isr); String message = br.readLine(); System.out.println("客户端说:" + message); System.out.println("一个客户端连接了"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { Server server = new Server(); server.start(); } }
需要先启动服务器端,客户端才启动。
服务端运行后,accept()方法hi引起程序的阻塞。
客户端代码:
package socket; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; /** * 聊天室客户端 * @author 小明 * */ public class Client { /** * 套接字 * 封装了TCP协议的通信细节,让我们可以简单地使用它完成TCP通讯 * Socket连接后提供了两条流,通过两条流的读写操作完成与远端计算机的数据连接 * 完成与远端计算机的数据交换。 */ private Socket socket; /** * 用来初始化客户端 */ public Client() { try { /** * 实例化Socket时需要传入两个参数: * 1:服务端的IP地址 * 2:服务端的端口号 * 通过IP地址可以找到服务端所在的计算机 * 通过端口可以找到运行在服务端计算机上的 * 服务端应用程序 * 注意,实例化Socket的过程就是连接的过程,若 * 连接失败就会抛出异常。 */ System.out.println("正在连接服务端..."); socket = new Socket("localhost", 8088); System.out.println("与服务端建立连接!"); /** * 有两个参数,一个是IP地址,一个是端口号 */ /** * 所有应用程序在使用网络的时候都要和操作系统申请一个网络端口 * */ /** * 异常要我们自己进行处理,不要抛出 */ }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 写程序时不要过度依赖main方法 * 客户端开始工作的方法 */ public void start() { try{ //socket.getOutputStream(); PrintWriter pw = new PrintWriter( new BufferedWriter( new OutputStreamWriter( socket.getOutputStream())), true); //pw.write("你好服务端"); //使用上面这条语句是错的,要使用具有自动行刷新的方法 //不要再下意识地写上面那条语句了 pw.println("你好服务端!"); }catch(Exception e){ e.printStackTrace(); } } public static void main(String[] args) { Client client = new Client(); client.start(); } }
建立第二个服务端时,发信息给服务端时没有反应。
因为只调用了一次accept()方法,所以接收不到信息。