Socket: 通过TCP协议进行通信

 

Java 为TCP 协议提供了两个类: Socket 类和ServerSocket 类.一个Socket 实例表示了TCP连接的一端。ServerSocket 实例监听TCP连接请求,并为每个请求创建新的Socket 实例。

也就是说服务器端要同时处理ServerSocket 实例和Socket实例, 客户端只需要使用 Socket 实例.

先看一个实例:

第一部分   创建TCP客户端,步骤如下:

1  创建一个Socket实例,构造函数向指定的远程主机和端口建立一个TCP连接

2  通过Socket套接字的输入输出流(I/O Stream) 进行通信

3  使用Socket类的close()关闭连接

代码:

/**
 * 通过TCP协议与回馈服务器(echo server)进行通信的客户端
 * 运行时参数 www.mkp.com "Echo this!" 80
 * 或 173.245.60.120 "Echo this!" 80
 */
public class TCPEchoClient {

 public static void main(String[] args) throws IOException
 {
  if(args.length < 2 || args.length > 3)
   throw new IllegalArgumentException("参数长度"+args.length+" Parameter(s):<Server> <Word> <Port>");
  String server = args[0];
  byte[] data = args[1].getBytes();
  
  int serverPort = (args.length == 3)?Integer.parseInt(args[2]) : 7;
  
  //创建连接到服务器Socket套接字连接
  System.out.println("server: "+server + "  serverPort: "+serverPort);
  Socket socket = new Socket(server,serverPort);
  System.out.println("连接到服务器... 发送响应字符");
  
  InputStream in = socket.getInputStream();
  OutputStream out = socket.getOutputStream();
  // 发送编码字符到服务端,这里写就是发送
  out.write(data);
  System.out.println("第二个参数字符"+args[1].toString());
  
  //以下从服务端接受相同的字符
  int totalBytesReceived = 0;    // 读取起点
  int bytesRcvd;       // 最后一次读取的字符数
  while(totalBytesReceived < data.length)
  {
   /**
    * 说明: 为什么不用不带参数的 read()方法?TCP协议并不能确定在read()和write()中所发送信息的界限
    * 也就是说,虽然只用了write()方法来发送响应字符串,响应服务器也可能从多个块(chunk)中接受该信息
    * 即使响应字符串在服务器上存于一个块中,在返回的时候,也可能被TCP协议分割成多个部分
    */
   bytesRcvd = in.read(data,totalBytesReceived,data.length - totalBytesReceived);
   if(bytesRcvd == -1)// -1 表示已读到最后
    throw new SocketException("Connectin  closed  prematurely");   //关闭连接过早,这里读就是接受
   totalBytesReceived += bytesRcvd;
  }
  System.out.println("Received: " + new String(data));
  socket.close(); 
 }
}

第二部分   创建TCP服务端,步骤如下:

1  创建一个ServerSocket 实例并指定本地端口。

2  重复执行:

    a   调用ServerSocket的accept() 方法以获取下一个客户端连接

    b   使用所返回的Socket 实例的InputStream 和 OutputStream 与客户端进行通信

    c   通信完成后,使用Socket 类的close() 关闭该客户端套接字连接

代码如下:

/**
 * TCP 服务器端
 * 运行参数 80
 */
public class TCPEchoServer {

 private static final int BUFSIZE = 32;
 public static void main(String[] args)throws IOException {
  
  if(args.length !=1)throw new IllegalArgumentException("Parameter(s): <Port>");
  int serverPort = Integer.parseInt(args[0]);
  
  //创建一个socket 服务连接,用于接受客户端连接请求
  ServerSocket  serverSocket = new ServerSocket(serverPort);
  int recMsgSize;
  byte[] receiveBuf = new byte[BUFSIZE]; //接收缓冲字符
  while(true)
  {
   Socket clientSocket = serverSocket.accept();
   SocketAddress clientAddress = clientSocket.getRemoteSocketAddress();
   System.out.println("处理客户端请求在  " + clientAddress);
   InputStream  in = clientSocket.getInputStream();
   OutputStream out = clientSocket.getOutputStream();
   //接受请求直到客户端关闭连接,显式由 -1 返回
   while((recMsgSize = in.read(receiveBuf)) != -1)
   {
    out.write(receiveBuf,0,recMsgSize);
   }
   clientSocket.close();
  }
 }
}

效果如下:

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值