用java自带的类库实现一个服务端和多个客户端收发信息的例子。
服务器的程序直接用一个mian方法启动的Server端来实现:
package test; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * 单线程Web服务器 * * @author deron * */ public class SingleThreadWebServer { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(7711); while (true) { Socket client = server.accept(); System.out.println("新增连接:"+client.getInetAddress()+":"+client.getPort()); handleReq(client); } } /** * 处理请求 * @param client */ private static void handleReq(Socket client) { System.out.println("处理客户端请求"); try { DataOutputStream outputStream=new DataOutputStream(client.getOutputStream()); outputStream.writeUTF("控制客户端输出字段"); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } outputStream.writeUTF("沉睡了10S后的操作"); outputStream.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
Socket client = server.accept();该语句调用了ServerSocket对象的accept()方法,这个方法的执行将使Server端的程序处于等待状态,程序将一直阻塞直到捕捉到一个来自Client端的请求,并返回一个用于与该Client通信的Socket对象Link-Socket。此后Server程序只要向这个Socket对象读写数据,就可以实现向远端的Client读写数据。
在本机或者另一台机器上用main方法创建一个client:
package test; import java.io.DataInputStream; import java.io.IOException; import java.net.Socket; public class Client1 { public static void main(String[] args) { try { Socket MySocket=new Socket("127.0.0.1",7711); DataInputStream inputStream=new DataInputStream(MySocket.getInputStream()); while(true){ System.out.println("receive_msg:"+inputStream.readUTF()); //inputStream.close(); //MySocket.close(); } } catch (IOException e) { e.printStackTrace(); } } }
在上面的代码启动后,服务端的控制台打印的值为:
新增连接:/127.0.0.1:62011 处理客户端请求
在客户端控制台打印的值为:
receive_msg:控制客户端输出字段 receive_msg:沉睡了10S后的操作
在开启服务端后,支持多个客户端连接到服务端,因为上述创建的是单线程服务端,所以要等上一个客户端的请求处理完才会处理下一个客户端的请求,因为上面的Server和Client端都有while(true)循环,所以客户端和服务端是一直连接随时接收信息的,如果客户端在新建Socket之后不用while的话,在执行一次请求之后立刻关闭,不管服务端有没有完成操作。在服务端延迟10S准备向客户端写信息时,报Connection reset by peer: socket write error的错误。