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 编程》 

  • 相关阅读:
    centos6下安装配置DNS(bind)
    centos6下安装配置NFS
    如何在kettle里面加载hadoop
    jQuery练习JavaScript事件与事件对象
    摆上殷勤的工作&职场用祷文
    Ajax自动完成(autocomplete)响应文本框输入后显示模糊数据列表
    未来的书香
    重要的计算机学习资料(累计中)
    W4F学习笔记之一
    软件测试重要资料汇集
  • 原文地址:https://www.cnblogs.com/xerrard/p/4250673.html
Copyright © 2011-2022 走看看