简介

    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();
  }
}