Java网络编程之TCP、UDP

时间:2022-12-18 00:00:46

Java网络编程之TCP、UDP

Java网络编程之TCP、UDP 分类:
       Java网络编程提供了两种协议:TCP(传输控制协议)和UDP(数据报协议)。TCP(Transmission Control Protocol)是一种可靠的传输协议,传输时会采用“三次握手”端的方式建立连接,以保证数据的可靠性和安全性;而UDP(User Datagram Protocol)协议是一种不可靠的传输协议,发送的数据不一定能够接受的到,网上的聊天是工具一般采用的此协议。下面将详细的接受TCP和UDP的使 用以及相应的编码。

一、TCP网络通信
       Java中使用Socket(套接字)实现TCP。服务器端使用ServerSocket类,客户端使用Socket类实现。
     
       1、ServerSocket类
        其主要有如下的方法:
       

          ServerSocket()   创建非绑定服务器套接字。
          ServerSocket(int port)  创建绑定到特定端口的服务器套接字。
        
          Socket accept()    侦听并接受到此套接字的连接。
           void close()    关闭此套接字
          boolean isClosed()   返回 ServerSocket 的关闭状态。
          InetAddress getInetAddress()    返回此服务器套接字的本地地址。
          void bind(SocketAddress endpoint)   将 ServerSocket 绑定到特定地址(IP 地址和端口号)。
          boolean isBound()   返回 ServerSocket 的绑定状态。
          SocketAddress getLocalSocketAddress()   返回此套接字绑定的端点的地址,如果尚未绑定则返回 null。
        
         服务器端每次运行是都要使用accept()方法等待客户端的连接,此方法执行之后服务器端将进入阻塞状态,知道客户端连接之后程序才继续执行,此方法返回是Socket,代表一个客户端对象。
        
       2、Socket类
       两台机器连接通信的端点。主要使用如下方法:
     
      Socket(String host, int port)  创建一个流套接字并将其连接到指定主机上的指定端口号。
      OutputStream getOutputStream()   返回此套接字的输出流。
      InputStream getInputStream()    返回此套接字的输入流。
      boolean isBound()    返回套接字的绑定状态。
      boolean isClosed()   返回套接字的关闭状态。
      boolean isConnected()     返回套接字的连接状态。
      void close()     关闭此套接字。
     其通过字节流和服务端进行通信。

      实例一、下面是实现一个简单的TCP客户端可服务器端通信。
   (1)服务器端:

[java] view plain copy Java网络编程之TCP、UDPJava网络编程之TCP、UDP
  1. package andy.network.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintStream;  
  5. import java.net.ServerSocket;  
  6. import java.net.Socket;  
  7.   
  8. /**   
  9.  * @author Zhang,Tianyou   
  10.  * version:2014-11-25 上午10:49:11   
  11.  *  
  12.  *   
  13.  */  
  14.   
  15. public class FirstTCPServer {  
  16.   
  17.     /** 
  18.      * @param args 
  19.      * @throws IOException  
  20.      */  
  21.     public static void main(String[] args) throws IOException {  
  22.         //创建服务器  
  23.         ServerSocket server = null;  
  24.         Socket socket = null;  
  25.         PrintStream out = null;  
  26.         //服务器在9999上等待客户端的访问  
  27.         server = new ServerSocket(9999);  
  28.           
  29.         System.out.println("服务器端已经运行,等待客户的响应。。。");  
  30.         //程序阻塞 等待客户端的访问  
  31.         socket = server.accept();  
  32.         //向客户端输出信息  
  33.         String str = "hello andy.";  
  34.           
  35.         out = new PrintStream(socket.getOutputStream());  
  36.         out.print(str);  
  37.         out.close();  
  38.         socket.close();  
  39.         server.close();  
  40.           
  41.     }  
  42.   
  43. }  


(2)客户端:

[java] view plain copy Java网络编程之TCP、UDPJava网络编程之TCP、UDP
  1. package andy.network.test;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6. import java.net.Socket;  
  7. import java.net.UnknownHostException;  
  8.   
  9. /** 
  10.  * @author Zhang,Tianyou  
  11.  * version:2014-11-25 上午11:02:17 
  12.  *  
  13.  *  
  14.  */  
  15.   
  16. public class FirstTCPSocket {  
  17.   
  18.     /** 
  19.      * @param args 
  20.      * @throws IOException 
  21.      * @throws UnknownHostException 
  22.      */  
  23.     public static void main(String[] args) throws UnknownHostException,  
  24.             IOException {  
  25.         // 定义客户端  
  26.         Socket client = null;  
  27.         // 设置地址和端口  
  28.         client = new Socket("localhost", 9999);  
  29.   
  30.         BufferedReader buf = null; // 结束服务端流  
  31.         buf = new BufferedReader(new InputStreamReader(client.getInputStream()));  
  32.         String str = buf.readLine();  
  33.         System.out.println("服务器端通知信息:" + str);  
  34.         buf.close();  
  35.         client.close();  
  36.   
  37.     }  
  38.   
  39. }  


   实例二
   实现客户端和服务器端的通信,服务器端可以响应多个客户端,每个客户端请求就启动一个线程。

    (1)服务端
 

[java] view plain copy Java网络编程之TCP、UDPJava网络编程之TCP、UDP
  1. package andy.network.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.ServerSocket;  
  5. import java.net.Socket;  
  6.   
  7. /** 
  8.  * @author Zhang,Tianyou  
  9.  * version:2014-11-25 上午11:41:22 
  10.  *  
  11.  *         聊天服务器端 
  12.  */  
  13.   
  14. public class ChatServer {  
  15.   
  16.     /** 
  17.      * @param args 
  18.      * @throws IOException 
  19.      */  
  20.     public static void main(String[] args) throws IOException {  
  21.   
  22.         ServerSocket server = null;  
  23.         Socket client = null;  
  24.         // 监听9999端口的连接  
  25.         server = new ServerSocket(9999);  
  26.         boolean  flag = true;  
  27.         while (flag) {  
  28.             System.out.println("服务器运行,等待客户端连接。");  
  29.             client = server.accept();  
  30.             // 对每一个客户端请求启动一个线程  
  31.             new Thread(new ChatThread(client)).start();  
  32.   
  33.         }  
  34.           
  35.         server.close();  
  36.   
  37.     }  
  38.   
  39. }  


 对应服务端线程任务:
 

[java] view plain copy Java网络编程之TCP、UDPJava网络编程之TCP、UDP
  1. package andy.network.test;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.InputStreamReader;  
  5. import java.io.PrintStream;  
  6. import java.net.Socket;  
  7.   
  8. /** 
  9.  * @author Zhang,Tianyou  
  10.  * version:2014-11-25 上午11:24:26 
  11.  *  
  12.  *         使用多线程机制,在每个用户响应之后启动一个新任务 
  13.  *  
  14.  */  
  15.   
  16. public class ChatThread implements Runnable {  
  17.   
  18.     // 接受客户端  
  19.     private Socket client = null;  
  20.   
  21.     public ChatThread(Socket client) {  
  22.         this.client = client;  
  23.     }  
  24.   
  25.     @Override  
  26.     public void run() {  
  27.         // 向客户端发送数据  
  28.         PrintStream out = null;  
  29.         // 接收客户端发来的数据  
  30.         BufferedReader buff = null;  
  31.         try {  
  32.             // 得到客户端的输入信息  
  33.             buff = new BufferedReader(new InputStreamReader(  
  34.                     client.getInputStream()));  
  35.             out = new PrintStream(client.getOutputStream());  
  36.             //标志是否一个客户端的操作完毕  
  37.             boolean flag = true;  
  38.               
  39.             while (flag) {  
  40.                 //不断的接收信息  
  41.                 String str = buff.readLine();  
  42.                 if(str == null || "".equals(str)){  
  43.                     flag = false;//客户端操作结束  
  44.                 }else{  
  45.                     if("bye".equals(str)){  
  46.                         flag = false;  
  47.                         out.println("bye-bye");   
  48.                     }else {  
  49.                         //向客户端回显输入  
  50.                         out.println("you input:" + str);  
  51.                     }  
  52.                 }  
  53.             }  
  54.               
  55.             out.close();  
  56.             client.close();  
  57.   
  58.         } catch (Exception e) {  
  59.             System.out.println("服务器异常!");   
  60.         }  
  61.   
  62.     }  
  63.   
  64. }  


(2)客户端

[java] view plain copy Java网络编程之TCP、UDPJava网络编程之TCP、UDP
  1. package andy.network.test;  
  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.UnknownHostException;  
  9.   
  10. /** 
  11.  * @author Zhang,Tianyou  
  12.  * version:2014-11-25 上午11:53:03 
  13.  *  
  14.  *         聊天客户端程序 
  15.  *  
  16.  */  
  17.   
  18. public class ChatClient {  
  19.   
  20.     public static void main(String[] args) throws UnknownHostException,  
  21.             IOException {  
  22.   
  23.         Socket client = null;  
  24.         client = new Socket("localhost", 9999);  
  25.         // 接收服务器端的信息  
  26.         BufferedReader buff = null;  
  27.         // 向服务器端发送数据  
  28.         PrintStream out = null;  
  29.         BufferedReader input = null;  
  30.         // 获取键盘输入数据  
  31.         input = new BufferedReader(new InputStreamReader(System.in));  
  32.   
  33.         out = new PrintStream(client.getOutputStream());  
  34.   
  35.         buff = new BufferedReader(  
  36.                 new InputStreamReader(client.getInputStream()));  
  37.         // 标志位  
  38.         boolean flag = true;  
  39.         while (flag) {  
  40.             System.out.println("输入信息:");  
  41.             String str = input.readLine();  
  42.             // 向服务器端输出信息  
  43.             out.println(str);  
  44.   
  45.             if ("bye".equals(str)) {  
  46.                 flag = false;  
  47.             } else {  
  48.                 String chatCont = buff.readLine();  
  49.                 System.out.println(chatCont);  
  50.             }  
  51.   
  52.         }  
  53.   
  54.         client.close();  
  55.         buff.close();  
  56.     }  
  57.   
  58. }  


二、UDP网络通信
   TCP的通信是建立在可靠通信的基础上,UDP则是不可靠的通信,使用数据报形式发送数据。
   在Java中主要有DatagramPacket和DatagramSocket实现。

  1、DatagramPacket主要方法
       DatagramPacket(byte[] buf, int length)
            构造 DatagramPacket,用来接收长度为 length 的数据包。
      DatagramPacket(byte[] buf, int length, InetAddress address, int port)
           构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
      byte[] getData()
            返回数据缓冲区。
     int getLength()
          返回将要发送或接收到的数据的长度。

 2、DatagramSocket主要方法
     DatagramSocket(int port)
            创建数据报套接字并将其绑定到本地主机上的指定端口。
     void receive(DatagramPacket p)
            从此套接字接收数据报包。
     void send(DatagramPacket p)
            从此套接字发送数据报包。
 在使用UDP时,先使用客户端指定好要接受的数据和端口。然后开启服务端发送数据。

实现如下:
(1)客户端

[java] view plain copy Java网络编程之TCP、UDPJava网络编程之TCP、UDP
  1. package andy.network.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.DatagramPacket;  
  5. import java.net.DatagramSocket;  
  6.   
  7. /** 
  8.  * @author Zhang,Tianyou  
  9.  * version:2014-11-25 下午3:04:10 
  10.  *  
  11.  *         UDP客户端 
  12.  */  
  13.   
  14. public class UDPClient {  
  15.   
  16.     /** 
  17.      * @param args 
  18.      * @throws IOException 
  19.      */  
  20.     public static void main(String[] args) throws IOException {  
  21.         // 客户在9999端口监听  
  22.         DatagramSocket dSocket = null;  
  23.         dSocket = new DatagramSocket(9999);  
  24.         // 定义接收数据的字节长度  
  25.         byte[] buff = new byte[1024];  
  26.         DatagramPacket dPacket = null;  
  27.         // 指定接收数据的长度1024  
  28.         dPacket = new DatagramPacket(buff, 1024);  
  29.         System.out.println("等待接受数据。。");  
  30.         //接收数据  
  31.         dSocket.receive(dPacket);  
  32.         String str = new String(dPacket.getData(), 0, dPacket.getLength())  
  33.                 + "from" + dPacket.getAddress().getHostAddress() + ":"  
  34.                 + dPacket.getPort();  
  35.         System.out.println(str);  
  36.         //关闭数据报套接字  
  37.         dSocket.close();  
  38.     }  
  39.   
  40. }  


  (2)服务器端

[java] view plain copy Java网络编程之TCP、UDPJava网络编程之TCP、UDP
  1. package andy.network.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.DatagramPacket;  
  5. import java.net.DatagramSocket;  
  6. import java.net.InetAddress;  
  7.   
  8. /**   
  9.  * @author Zhang,Tianyou   
  10.  * version:2014-11-25 下午3:13:38   
  11.  *  
  12.  * UDP服务器端 
  13.  *   
  14.  */  
  15.   
  16. public class UDPServer {  
  17.   
  18.     /** 
  19.      * @param args 
  20.      * @throws IOException  
  21.      */  
  22.     public static void main(String[] args) throws IOException {  
  23.         DatagramSocket dSocket = null;  
  24.         //服务端在3333端口监听  
  25.         dSocket = new DatagramSocket(3333);  
  26.         DatagramPacket dPacket = null;  
  27.         //要发生的数据  
  28.         String str = "hello andy!";  
  29.         //向目标端口地址发送数据报  
  30.         dPacket = new DatagramPacket(str.getBytes(), str.length(),  
  31.                 InetAddress.getByName("localhost") , 9999);  
  32.           
  33.         System.out.println("发送数据报");   
  34.           
  35.         dSocket.send(dPacket);  
  36.         dSocket.close();  
  37.   
  38.     }  
  39.   
  40. }  
Java网络编程之TCP、UDP