简介
TCP通信严格区分客户端和服务器端,通信时客户端发起请求连接服务器端才能实现通信,服务器端不能主动连接客户端。Java为TCP协议提供了两个类:Socket类和ServerSocket类,一个Socket实例代表了TCP连接的客户端,而ServerSocket实例代表了TCP连接的服务器端。一个TCP连接是一条抽象的双向通道,两端分别由IP地址和端口号确定。开始通信之前,要建立一个TCP连接,这需要先由客户端TCP向服务端TCP发送连接请求。ServerSocket实例则监听TCP连接请求,并为每个请求创建新的Socket实例,也就是说服务器端要同时处理ServerSocket实例和Socket实例,而客户端只需要使用Socket实例。
TCP通信
TCP客户端:
客户端向服务器发起连接请求,就被动地等待服务器的响应。典型的TCP客户端要经过下面三步。
1.创建一个Socket实例:构造函数向指定的远程主机和端口建立一个TCP连接。
2.通过套接字的输入输出流进行通信,一个Socket连接实例包括了一个InputStream和一个OutputStream。
3.使用Socket类的close()方法关闭连接。
TCP服务器端:
服务器端的工作是创建一个通信终端,并被动地等待客户端的连接。典型的TCP服务器质性如下工作:
1.创建一个ServerSocket实例并指定本地端口。此套接字的功能是监听改指定端口收到的连接。
2.重复执行:
a.调用ServerSocket的accept()方法以获取下一个客户端连接。基于新创建的客户端连接,创建一个Socket实例,并由accept()方法返回。
b.使用所返回的Socket实例的InputStream和OutputStream与客户端进行通信。
c.通信完成后,使用Socket类的close()方法关闭该客户端套接字连接。
TCP通信案例
以下代码实现了客户端发送文件到服务器端,服务器端进行接收并保存文件,接收完文件给客户端反馈。
此案例使用多线程实现的,由此服务端可以接收到多个客户端发送过来的文件。
public class TCPClient {
public static void main(String[] args) {
try {
Socket clientSocket = new Socket("127.0.0.1", 1234);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\java.txt"));
OutputStream out = clientSocket.getOutputStream();
int len = 0;
byte[] buffer = new byte[1027];
while ((len = bis.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
// 数据传送完毕,关闭socket输出操作,告知服务器端
clientSocket.shutdownOutput();
// ---------读取服务器端的反馈信息
InputStream in = clientSocket.getInputStream();
byte[] message = new byte[1024];
int length = in.read(message);
System.out.println(new String(message, 0, length));
// 关闭套接字和流
clientSocket.close();
bis.close();
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ServerTask implements Runnable {
private Socket clientSocket;
public ServerTask(Socket socket) {
this.clientSocket = socket;
}
@Override
public void run() {
try {
InetAddress address = clientSocket.getInetAddress();
System.out.println("message from ip:" + address.getHostAddress());
InputStream in = clientSocket.getInputStream();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\upload"+System.currentTimeMillis()+".txt"));
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
// --------给客户端反馈
OutputStream out = clientSocket.getOutputStream();
out.write("finish the job".getBytes());
in.close();
bos.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class TCPServer {
public static void main(String[] args) throws IOException {
//监听端口1234
ServerSocket serverSocket = new ServerSocket(1234);
while(true) {
//请求启用一个线程处理
Socket clientSocket = serverSocket.accept();
new Thread(new ServerTask(clientSocket)).start();
}
//serverSocket.close();
}
}