先前的一篇博文(C语言socket编程实现TCP通信),在unix系统下,利用C语言socket编程简单实现了客户端服务端TCP通信。实际上,利用java.net包中的类可以更容易的进行socket通信。
但不管是使用java还是C语言进行socket编程,TCP通信本质上是一样的。都是服务端端绑定一个端口并对此端口进行监听,客户端根据IP和端口访问服务端,两者通过三次握手建立连接,然后就可以通过socket上绑定的读写流进行读写,从而实现通信。服务端上存在两个socket,一个serverSocket用于监听客户端连接,另一个clientSocket是接收客户端连接请求时创建的一个用于与客户端通信的socket。
java socket编程实现TCP通信示例如下:
(1)服务端:
(a) 创建ServerSocket对象,得到serverSocket;
(b) 利用该对象的方法bind(int port)绑定一个监听端口;
(c) 利用该对象的方法accept()接收客户端连接请求并建立连接,得到一个Socket类的对象clientSocket,调用该方法服务端进程会阻塞等待连接请求到来。
(d) 通过clientSocket上的读写流与客户端进行通信。
(2)服务端:
(a) 创建Socket对象,用构造方法socket(String ip, int port)可以得到一个clientSocket用于与服务端通信,并与客户端上指定IP和端口建立连接;
(c) 通过clientSocket上的读写流与服务端进行通信。
具体代码如下:
1. SocketServer.java
import java.net.* ; import java.io.* ; import java.util.Scanner; public class SocketServer { public static void main(String[] args) { int port = 29111; SocketServer server = new SocketServer(); server.serverTest(port); } public void serverTest (int port) { ServerSocket serverSocket = null; try{ //bind and listen port serverSocket = new ServerSocket(port); System.out.println("bind port: " + port); //accept connection and communicate byte[] buf = new byte[512]; int bufLen = -1; Socket clientSocket = null; InputStream input = null; OutputStream output = null; String str = null; Scanner sc = new Scanner(System.in); while(true){ //accept System.out.println("waiting connection..."); clientSocket = serverSocket.accept(); input = clientSocket.getInputStream(); output = clientSocket.getOutputStream(); System.out.println("client ip and port: " + clientSocket.getInetAddress().toString() + ":"+clientSocket.getPort()); System.out.println("ready"); //read while(true){ bufLen = input.read(buf); str = new String(buf, 0, bufLen); System.out.println("client: " + str); if(str.equals("close")){ break; } //write System.out.print("server: "); str = sc.nextLine(); output.write(str.getBytes()); if(str.equals("kill") || str.equals("close")){ break; } } //close System.out.println("close client"); input.close(); output.close(); clientSocket.close(); if(str.equals("kill")){ System.out.println("close server"); serverSocket.close(); sc.close(); break; } } }catch(Exception e){ e.printStackTrace(); } } }
2. SocketClient.java
import java.net.* ; import java.io.* ; import java.util.Scanner; public class SocketClient { public static void main(String[] args) { int port = 29111; String ip = new String("127.0.0.1"); SocketClient client = new SocketClient(); client.clientTest(ip, port); } public void clientTest(String ip, int port){ Socket clientSocket = null; InputStream input = null; OutputStream output = null; Scanner sc = new Scanner(System.in); String str = null; byte[] buf = new byte[512]; //connect and communicate try { //connect clientSocket = new Socket(ip, port); input = clientSocket.getInputStream(); output = clientSocket.getOutputStream(); System.out.println("try to connect server "+ ip + ": " + port); System.out.println("ready"); //write and read while(true){ System.out.print("client: "); str = sc.nextLine(); output.write(str.getBytes()); if(str.equals("close")){ break; } int len = input.read(buf); str = new String(buf, 0, len); System.out.println("server: " + str); if(str.equals("kill") || str.equals("close")){ break; } } //close input.close(); output.close(); sc.close(); clientSocket.close(); } catch (Exception e) { e.printStackTrace(); } } }
测试结果如下:
如果客户端或者服务端输入close则关闭客户端与服务端的连接,客户端进程退出,但是服务端仍旧处于监听状态;如果服务端输入kill,则关闭客户端服务端连接,并且停止客户端和服务端进程。