zoukankan      html  css  js  c++  java
  • Java TCP Socket编程

    1.TCP Socket在Java上的实现

    Java 为 TCP 协议提供了两个类:Socket 类和 ServerSocket 类。一个 Socket 实例代表了TCP 连接的一端。一个 TCP 连接(TCP connection)是一条抽象的双向信道,两端分别由 IP地址和端口号确定。在开始通信之前,要建立一个 TCP 连接,这需要先由客户端 TCP 向服务器端 TCP 发送连接请求。ServerSocket 实例则监听 TCP 连接请求,并为每个请求创建新的 Socket 实例。也就是说,服务器端要同时处理 ServerSocket 实例和 Socket 实例,而客户端只需要使用 Socket 实例。每个Socket实例会关联一个InputStream和OutputStream对象,我们通过将字节写入套接字的OutputStream来发送数据,并通过从InputStream来接收数据。

    2.TCP连接的建立步骤

      客户端向服务器端发送连接请求后,就被动地等待服务器的响应。典型的TCP客户端要经过下面三步操作: 

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

       2.通过套接字的I/O流与服务端通信;

       3、使用Socket类的close方法关闭连接。

      服务端的工作是建立一个通信终端,并被动地等待客户端的连接。典型的TCP服务端执行如下两步操作:

         1、创建一个ServerSocket实例并指定本地端口,用来监听客户端在该端口发送的TCP连接请求;

         2、重复执行:

               1)调用ServerSocket的accept()方法以获取客户端连接,并通过其返回值创建一个Socket实例;

               2)为返回的Socket实例开启新的线程,并使用返回的Socket实例的I/O流与客户端通信;

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

            绘图1

    3.TCP Demo

    Demo1.基本的流发送示例:

    服务端开启一个TCP服务器,参数为端口号

    客户端启动一个TCP服务,参数为服务端的地址,发送的字符,端口号

     1 import java.net.Socket;
     2 import java.net.SocketException;
     3 import java.io.IOException;
     4 import java.io.InputStream;
     5 import java.io.OutputStream;
     6 
     7 public class TCPClient {
     8 
     9     public static void main(String[] args) throws IOException {
    10 
    11         if ((args.length < 2) || (args.length > 3))
    12 
    13             throw new IllegalArgumentException(
    14                     "Parameter(s):<Server> <Word> [<Port>]");
    15 
    16         String server = args[0]; // Server name or IP address
    17         /* Convert argument String to bytes using the default character encoding */
    18         byte[] senddata = args[1].getBytes();
    19         int servPort = (args.length == 3) ? Integer.parseInt(args[2]) : 7;
    20         /* Create socket that is connected to server onspecified port*/
    21         Socket socket = new Socket(server, servPort);
    22         System.out.println("Connected to server...sending echo string");
    23 
    24         InputStream in = socket.getInputStream();
    25         OutputStream out = socket.getOutputStream();
    26         out.write(senddata); // Send the encoded string to the server
    27 
    28         int totalBytesRcvd = 0; // Total bytes received so far
    29         byte[] recvdata = new byte[in.available()];
    30         int bytesRcvd; // Bytes received in last read
    31         while (totalBytesRcvd < recvdata.length) {
    32             if ((bytesRcvd = in.read(recvdata, totalBytesRcvd, recvdata.length
    33                     - totalBytesRcvd)) == -1)
    34                 throw new SocketException("Connection closed prematurely");
    35             totalBytesRcvd += bytesRcvd;
    36         } // data array is full
    37 
    38         System.out.println("Received: " + new String(recvdata));
    39 
    40         socket.close(); // Close the socket and its streams
    41     }
    42 }
    TCPClient
     1 import java.net.*; // for Socket, ServerSocket, andInetAddress
     2 import java.io.*; // for IOException and Input/OutputStream
     3 
     4 public class TCPServer {
     5 
     6     private static final int BUFSIZE = 32; // Size of receivebuffer
     7 
     8     public static void main(String[] args) throws IOException {
     9 
    10         if (args.length != 1) // Test for correct # of args
    11             throw new IllegalArgumentException("Parameter(s): <Port>");
    12 
    13         int servPort = Integer.parseInt(args[0]);
    14 
    15         /* Create a server socket to accept client connection requests */
    16         ServerSocket servSock = new ServerSocket(servPort);
    17 
    18         int recvMsgSize; // Size of received message
    19         byte[] receiveBuf = new byte[BUFSIZE]; // Receive buffer
    20 
    21         while (true) { // Run forever, accepting and servicing connections
    22 
    23             Socket clntSock = servSock.accept(); // Get client connection
    24 
    25             SocketAddress clientAddress = clntSock.getRemoteSocketAddress();
    26 
    27             System.out.println("Handling client at " + clientAddress);
    28 
    29             InputStream in = clntSock.getInputStream();
    30             OutputStream out = clntSock.getOutputStream();
    31 
    32             /* Receive until client closes connection, indicated by -1 return*/
    33 
    34             while ((recvMsgSize = in.read(receiveBuf)) != -1) {
    35 
    36                 out.write(receiveBuf, 0, recvMsgSize);
    37             }
    38             clntSock.close(); // Close the socket. We are done with this client!
    39         }
    40         /* NOT REACHED */
    41 
    42     }
    43 }
    TCPServer

    Demo2.

    客户端从控制台输入字符串,发送到服务端

    服务端受到客户端的字符串后,加上部分信息(echo字符串)返回到客户端

     1 package zyb.org.client;
     2 
     3 import java.io.BufferedReader;
     4 import java.io.IOException;
     5 import java.io.InputStreamReader;
     6 import java.io.PrintStream;
     7 import java.net.Socket;
     8 import java.net.SocketTimeoutException;
     9 
    10 public class Client {
    11     public static void main(String[] args) throws IOException {
    12         //客户端请求与本机在20006端口建立TCP连接 
    13         Socket client = new Socket("127.0.0.1", 20006);
    14         client.setSoTimeout(10000);
    15         //获取键盘输入 
    16         BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    17         //获取Socket的输出流,用来发送数据到服务端  
    18         PrintStream out = new PrintStream(client.getOutputStream());
    19         //获取Socket的输入流,用来接收从服务端发送过来的数据  
    20         BufferedReader buf =  new BufferedReader(new InputStreamReader(client.getInputStream()));
    21         boolean flag = true;
    22         while(flag){
    23             System.out.print("输入信息:");
    24             String str = input.readLine();
    25             //发送数据到服务端  
    26             out.println(str);
    27             if("bye".equals(str)){
    28                 flag = false;
    29             }else{
    30                 try{
    31                     //从服务器端接收数据有个时间限制(系统自设,也可以自己设置),超过了这个时间,便会抛出该异常
    32                     String echo = buf.readLine();
    33                     System.out.println(echo);
    34                 }catch(SocketTimeoutException e){
    35                     System.out.println("Time out, No response");
    36                 }
    37             }
    38         }
    39         input.close();
    40         if(client != null){
    41             //如果构造函数建立起了连接,则关闭套接字,如果没有建立起连接,自然不用关闭
    42             client.close();    //只关闭socket,其关联的输入输出流也会被关闭
    43         }
    44     }
    45 }
    客户端代码Client
     1 package zyb.org.server;
     2 
     3 import java.net.ServerSocket;
     4 import java.net.Socket;
     5 
     6 public class Server {
     7     public static void main(String[] args) throws Exception{
     8         //服务端在20006端口监听客户端请求的TCP连接
     9         ServerSocket server = new ServerSocket(20006);
    10         Socket client = null;
    11         boolean f = true;
    12         while(f){
    13             //等待客户端的连接,如果没有获取连接
    14             client = server.accept();
    15             System.out.println("与客户端连接成功!");
    16             //为每个客户端连接开启一个线程
    17             new Thread(new ServerThread(client)).start();
    18         }
    19         server.close();
    20     }
    21 }
    服务端代码Server
     1 package zyb.org.server;
     2 
     3 import java.io.BufferedReader;
     4 import java.io.InputStreamReader;
     5 import java.io.PrintStream;
     6 import java.net.Socket;
     7 
     8 /**
     9  * 该类为多线程类,用于服务端
    10  */
    11 public class ServerThread implements Runnable {
    12 
    13     private Socket client = null;
    14     public ServerThread(Socket client){
    15         this.client = client;
    16     }
    17     
    18     @Override
    19     public void run() {
    20         try{
    21             //获取Socket的输出流,用来向客户端发送数据
    22             PrintStream out = new PrintStream(client.getOutputStream());
    23             //获取Socket的输入流,用来接收从客户端发送过来的数据
    24             BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
    25             boolean flag =true;
    26             while(flag){
    27                 //接收从客户端发送过来的数据
    28                 String str =  buf.readLine();
    29                 if(str == null || "".equals(str)){
    30                     flag = false;
    31                 }else{
    32                     if("bye".equals(str)){
    33                         flag = false;
    34                     }else{
    35                         //将接收到的字符串前面加上echo,发送到对应的客户端
    36                         out.println("echo:" + str);
    37                     }
    38                 }
    39             }
    40             out.close();
    41             client.close();
    42         }catch(Exception e){
    43             e.printStackTrace();
    44         }
    45     }
    46 
    47 }
    服务端代码 线程类 ServerThread

    参考文章:

    【Java TCP/IP Socket】TCP Socket(含代码)  http://blog.csdn.net/ns_code/article/details/14105457

    《Java TCP/IP Socket 编程》 

  • 相关阅读:
    【Codeforces 349B】Color the Fence
    【Codeforces 459D】Pashmak and Parmida's problem
    【Codeforces 467C】George and Job
    【Codeforces 161D】Distance in Tree
    【Codeforces 522A】Reposts
    【Codeforces 225C】Barcode
    【Codeforces 446A】DZY Loves Sequences
    【Codeforces 429B】Working out
    【Codeforces 478C】Table Decorations
    【Codeforces 478C】Table Decorations
  • 原文地址:https://www.cnblogs.com/xerrard/p/4250673.html
Copyright © 2011-2022 走看看