java实现基础的一对一和一对多的TCP通信

来源:互联网 发布:硬盘坏了数据恢复价格 编辑:程序博客网 时间:2024/05/22 06:11

本文探讨一下java的TCP通信,首先先实现一对一的tcp连接:

先来看一下tcp的特点:

面向连接的TCP 

     TCP面向连接通信,所以握手过程会消耗资源,过程为可靠连接,不会丢失数据,适合大数据量交换 

     “面向连接”就是在正式通信前必须要与对方建立起连接。
     TCP协议能为应用程序提供可靠的通信连接,使一台计算机发出的字节流无差错地发往网络上的其他计算机,对可靠性要求高的数据通信系统往往使用TCP协议传输数据。

下面实现一对一的tcp,首先写一个Server类做服务器,放在com.tcp包下,注释写得很清楚了,请注意看注释:


[java] view plain copy
  1. package com.tcp;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.io.OutputStream;  
  8. import java.io.PrintWriter;  
  9. import java.net.ServerSocket;  
  10. import java.net.Socket;  
  11.   
  12. /* 
  13.  * ServerSocket测试 作为tcp网络通信的服务器端 
  14.  * 1、创建ServerSocket对象,绑定监听端口 
  15.  * 2、通过accept()方法监听客户端请求 
  16.  * 3、连接建立后,通过输入流读取客户端发送的请求信息  
  17.  * 4、通过输出流向客户端发送响应信息 
  18.  * 5、关闭相关资源 
  19.  * */  
  20. public class Server {  
  21.     public static void main(String[] args) {  
  22.         try {  
  23.             //1、创建一个服务器端Socket,即ServerSocket,绑定指定的端口,进行监听  
  24.             ServerSocket serverSocket = new ServerSocket(8888);  
  25.             System.out.println("服务器即将启动,等待客户端连接");  
  26.             //2、调用accept()方法 开始监听 等待客户端连接  
  27.             Socket socket = serverSocket.accept();//ctrl+shift+o快速导入需要的包  
  28.             //3、获取输入流 并读取客户端信息  
  29.             InputStream is = socket.getInputStream();//字节输入流  
  30.             InputStreamReader isr = new InputStreamReader(is);//将字节流转化为字符流  
  31.             BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲  
  32.             String info=null;  
  33.             while((info = br.readLine())!=null){//循环读取客户端信息  
  34.                 System.out.println("我是服务器,客户端说"+info);  
  35.             }  
  36.             socket.shutdownInput();  
  37.             //4、获取输出流 响应客户端的请求  
  38.             OutputStream os= socket.getOutputStream();  
  39.             PrintWriter pw = new PrintWriter(os);//包装为打印流  
  40.             pw.write("欢迎您");  
  41.             pw.flush();//缓冲输出  
  42.             //5、关闭资源  
  43.             //服务器调用了socket.close()和serverSocket.close()以后就不需要调用其它close()方法了 因为相当于中断了连接 相应的流通道也断开了  
  44.             //同理客户端也是调用socket.close()就可以了  
  45.             socket.close();  
  46.             serverSocket.close();  
  47.         } catch (IOException e) {  
  48.             // TODO Auto-generated catch block  
  49.             e.printStackTrace();  
  50.         }  
  51.           
  52.     }  
  53. }  

接下来写一个Client类做客户端,同样放在com.tcp下:


[java] view plain copy
  1. package com.tcp;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.io.OutputStream;  
  8. import java.io.PrintWriter;  
  9. import java.net.Socket;  
  10. import java.net.UnknownHostException;  
  11.   
  12. /* 
  13.  * Socket测试  作为tcp的客户端: 
  14.  * 1、创建Socket对象,指明需要连接的服务器的地址和端口号 
  15.  * 2、连接建立以后,向服务器端发送请求信息 
  16.  * 3、通过输入流获取服务器响应的信息 
  17.  * 4、关闭相关资源 
  18.  * */  
  19. public class Client {  
  20.     public static void main(String[] args) {  
  21.         try {  
  22.             //1、创建客户端Socket,指定服务器地址和端口  
  23.             Socket socket = new Socket("localhost",8888);  
  24.             //2、获取输出流,向服务器发送信息  
  25.             OutputStream os = socket.getOutputStream();//字节输出流  
  26.             PrintWriter pw = new PrintWriter(os);//将输出流包装为打印流  
  27.             pw.write("我是客户端 我在说话");  
  28.             pw.flush();  
  29.             socket.shutdownOutput();//关闭输出流  
  30.             //3、获取输入流,并且读取服务器端的响应信息  
  31.             InputStream is = socket.getInputStream();  
  32.             BufferedReader br = new BufferedReader(new InputStreamReader(is));  
  33.             String info=null;  
  34.             while((info = br.readLine())!=null){//循环读取服务器信息  
  35.                 System.out.println("我是客户端,服务器说"+info);  
  36.             }  
  37.             //4、关闭资源  
  38. //            socket.close();  
  39.         } catch (UnknownHostException e) {  
  40.             // TODO Auto-generated catch block  
  41.             e.printStackTrace();  
  42.         } catch (IOException e) {  
  43.             // TODO Auto-generated catch block  
  44.             e.printStackTrace();  
  45.         }  
  46.           
  47.     }  
  48. }  

这样便实现了TCP的一对一通信。

下面我们来实现TCP的一对多连接,客户端的代码不需要改变,我们只需要改变服务器端的代码,让其循环监听客户端,然后新建一个线程类即可。

首先新建一个线程类ServerThread 放在com.tcp下:

[java] view plain copy
  1. package com.tcp;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.io.OutputStream;  
  8. import java.io.PrintWriter;  
  9. import java.net.Socket;  
  10.   
  11. /* 
  12.  * 服务器线程处理类 
  13.  * */  
  14. public class ServerThread extends Thread {  
  15.     //和本线程相关的Socket  
  16.     Socket socket = null;  
  17.       
  18.     public ServerThread(Socket socket){  
  19.         this.socket = socket;  
  20.     }  
  21.       
  22.     //线程执行的操作 响应客户端的请求  
  23.     public void run(){  
  24.         try {  
  25.             //3、获取输入流 并读取客户端信息  
  26.             InputStream is = socket.getInputStream();  
  27.             //字节输入流  
  28.             InputStreamReader isr = new InputStreamReader(is);//将字节流转化为字符流  
  29.             BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲  
  30.             String info=null;  
  31.             while((info = br.readLine())!=null){//循环读取客户端信息  
  32.                 System.out.println("我是服务器,客户端说"+info);  
  33.             }  
  34.             socket.shutdownInput();  
  35.             //4、获取输出流 响应客户端的请求  
  36.             OutputStream os= socket.getOutputStream();  
  37.             PrintWriter pw = new PrintWriter(os);//包装为打印流  
  38.             pw.write("欢迎您");  
  39.             pw.flush();//缓冲输出  
  40.             //5、关闭资源  
  41.             //服务器调用了socket.close()和serverSocket.close()以后就不需要调用其它close()方法了 因为相当于中断了连接 相应的流通道也断开了  
  42.             //同理客户端也是调用socket.close()就可以了  
  43.         }   
  44.         catch (IOException e) {  
  45.             // TODO Auto-generated catch block  
  46.             e.printStackTrace();  
  47.         }  
  48.         finally{//无论如何都关闭socket  
  49.             if(socket!=null){  
  50.                 try {  
  51.                     socket.close();  
  52.                 } catch (IOException e) {  
  53.                     // TODO Auto-generated catch block  
  54.                     e.printStackTrace();  
  55.                 }  
  56.             }  
  57.         }  
  58.     }  
  59. }  

然后将服务器端的代码在线程类的基础上进行一下变化:

[java] view plain copy
  1. package com.tcp;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.io.OutputStream;  
  8. import java.io.PrintWriter;  
  9. import java.net.ServerSocket;  
  10. import java.net.Socket;  
  11.   
  12. /* 
  13.  * ServerSocket测试 作为tcp网络通信的服务器端 
  14.  * 1、创建ServerSocket对象,绑定监听端口 
  15.  * 2、通过accept()方法监听客户端请求 
  16.  * 3、连接建立后,通过输入流读取客户端发送的请求信息  
  17.  * 4、通过输出流向客户端发送响应信息 
  18.  * 5、关闭相关资源 
  19.  * */  
  20. public class Server {  
  21.     public static void main(String[] args) {  
  22.         try {  
  23.             //记录链接过的客户端个数  
  24.             int count=0;  
  25.             //1、创建一个服务器端Socket,即ServerSocket,绑定指定的端口,进行监听  
  26.             ServerSocket serverSocket = new ServerSocket(8888);  
  27.             System.out.println("服务器即将启动,等待客户端连接");  
  28.             //2、循环监听等待客户端的连接  
  29.             while(true){  
  30.                 //调用accept方法 等待客户端的连接  
  31.                 Socket socket = serverSocket.accept();  
  32.                 //创建一个新的线程  
  33.                 ServerThread serverThread = new ServerThread(socket);  
  34.                 //启动线程  
  35.                 serverThread.start();  
  36.                 count++;  
  37.                 System.out.println("连接过的客户端数量为:"+count);  
  38.             }  
  39. //            serverSocket.close();//这是一个死循环 所以执行不到这里 服务器会一直运行  
  40.         } catch (IOException e) {  
  41.             // TODO Auto-generated catch block  
  42.             e.printStackTrace();  
  43.         }  
  44.           
  45.     }  
  46. }  

到这里,我们就完成了一个很基础的一对一tcp和一对多tcp连接。
原创粉丝点击