先前的一篇博文(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,则关闭客户端服务端连接,并且停止客户端和服务端进程。