服务器端的工作是建立一个通信终端,并被动地等待客户端的连接
典型TCP服务端执行以下步骤
1.创建一个serverSocket实例并指定本地端口,此套接字的功能是侦听该指定端口收到的连接。
ServerSocket socket= new ServerSocket(port);
2.重复执行:
a. 调用ServerSocket的accept()方法以获取下一个客户端连接。基于新建立的客户端连接,创建一个Socket实例,
并由accept()方法返回。
/**
*accept()方法再接收到客户端请求之前将一直处于阻塞状态。(不支持多个客户端同时访问)
*/
Socket clientSocket = servSocket.accept();
b. 使用所返回的Socket实例的InputStream和OutputStream与客户端进行通信。
InputStream in = clientSocket.getInputStream();
OutputStream out = clientSocket.getOutputStream();
c. 通信完成后,使用Socket类的close()方法关闭该客户端套接字连接。
clientSocket.close();
下面是一段socket服务端代码的例子
package TCPIP.tcpInstance;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
public class TCPEchoServer {
// Size of receive buffer
private static final int BUFSIZE = 64;
/**
* @param args
*/
public static void main(String[] args) {
String array[]={"9002"};
// Test for correct # of args
if (array.length != 1) {
throw new IllegalArgumentException("Parameter(s):<Port>");
}
int servPort = Integer.parseInt(array[0]);
// Create a server socket to accept client connection request
ServerSocket servSocket = null;
int recvMsgSize = 0;
byte[] receivBuf = new byte[BUFSIZE];
try {
servSocket = new ServerSocket(servPort);
while (true) {
Socket clientSocket = servSocket.accept();
SocketAddress clientAddress = clientSocket
.getRemoteSocketAddress();
System.out.println("Handling client at " + clientAddress);
InputStream in = clientSocket.getInputStream();
OutputStream out = clientSocket.getOutputStream();
while ((recvMsgSize = in.read(receivBuf)) != -1) {
String receivedData = new String(receivBuf.toString());
System.out.println(receivedData);
out.write(receivBuf, 0, recvMsgSize);
}
clientSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
- ServerSocket实例的唯一目的,是为新的TCP连接请求提供一个新的已连接的Socket实例。
- 当服务器端已经准备好处理客户端请求时,就调用accept()方法。该方法将阻塞等待,直到有向ServerSocket实例指定端口的新的连接请求到来。
- ServerSocket类的accept()方法将返回一个Socket实例,该实例已经连接到了远程客户端的套接字,并已准备好读写数据。
- 在新创建的Socket实例中,我们可以查询所连接的客户端的相应地址和端口号。Socket类的getRemoteSocketAddress()方法返回一个包含了客户端地址和端口号的InetSocketAddress实例。
- InetSocketAddress类的toString()方法以"/_address_:_port_"的形式打印出这些信息。
- 写入这个服务器端套接字的OutputStream的字节信息将从客户端套接字的InputStream中读出,而写入客户端OutputStream的字节信息将从服务器端套接字的InputStream读出
(未完待补充)