JAVA-Socket通信笔记

简介:

TCP 的 Java 支持

  协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP 协议族有 IP 协议、TCP 协议和 UDP 协议。现在 TCP/IP 协议族中的主要 socket 类型为流套接字(使用 TCP 协议)和数据报套接字(使用 UDP 协议)。

 

  Socket套接字 是面向连接的通信,基于TCP/IP协议提供了稳定的支持(Ps: TCP/IP 传输效率低于 UDP),TCP/IP 提供了Socket和Serversocket两个类, 使用 Serversocket 实例来监听端口是否 有客户端请求,并通过 accept()方法 来返回一个Socket 实例,客户端的socket和服务端的socket 就这样建立了连接,每个socket 有自己的io流 ,那么服务端的输入流对应客户端的输出流,客户端的输出流对应服务端的输入流,在这里输入流 我们采用(BufferedReader)包装流,输入采用(PrintStream)包装流,通过包装流 包装 输入输初流,可以方便程序数据的使用。

 

典型的 TCP 服务端执行如下两步操作

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

  1. 重复执行:

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

  • 为返回的 Socket 实例开启新的线程,并使用返回的 Socket 实例的 I/O 流与客户端通信; 通信完成后,使用 Socket 类的 close()方法关闭该客户端的

套接字连接。

 

好了话不多说,下面贴程序。

 

***服务端代码***

 1 package socket多客户端; 2  3  4 import java.io.IOException; 5 import java.net.*; 6 import java.util.ArrayList; 7 public class Server { 8      9     private static ArrayList<Thread_Client> list = new ArrayList<>();10     11     private static final int PORT = 6789;12     private static ServerSocket serverSocket;13     private static Socket socket;14     15     static void send(String string){16         17         // 使用 for 循环 , 遍历Arraylist 广播某客户端传来的消息18         for(Thread_Client thread_Client : list){19             //  调用 子线程的 send 方法20             thread_Client.send(string);21         }22         23     }24     25     26     public static void main(String[] args) {27         28         29         30         System.out.println("服务端开始运行...");31         32         try {33             34             serverSocket = new ServerSocket(PORT);35             36             while(true){37                 socket = serverSocket.accept();38                 Thread_Client thread_Client = new Thread_Client(socket);39                 thread_Client.start();40                 System.out.println("已连接!");41                 list.add(thread_Client);42                 43             }44             45             46         } catch (Exception e) {47             // TODO: handle exception48             System.out.println("服务端异常1");49         }finally {50             51             try {52                 socket.close();53                 serverSocket.close();54                 55             } catch (IOException e2) {56                 // TODO: handle exception57                 System.out.println("服务端异常2");58             }59             60         }61         62     }63 64 }

 

*** 然后是 处理连接后socket 的子线程***

 1 package socket多客户端; 2  3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.io.PrintStream; 7 import java.lang.*; 8 import java.net.Socket; 9 10 public class Thread_Client  extends Thread{11     12     private BufferedReader bufferedReader = null;13     private PrintStream printStream = null;14     15     Socket socket;16     17     public Thread_Client(Socket socket) {18         //19         this.socket = socket;20     }21 22     @Override23     public void run() {24         // TODO Auto-generated method stub25         super.run();26         27         try {28             Get_Set(socket);29             30         } catch (Exception e) {31             // TODO: handle exception32             System.out.println("异常1");33         }34         35     }36     37     public void send(String string){38         if(string != null){39             printStream.println(string);40             printStream.flush();41         }42     }43     44     public void Get_Set(Socket socket){45         46         try {47             bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));48             printStream = new PrintStream(socket.getOutputStream());49             50             Boolean flag = true;51             while(flag){52                 String string = bufferedReader.readLine();53                 if("".equals(string) || string == null){54                     flag = false;55                 }else{56                     if("end".equals(string)){57                         flag = false;58                     }else{59                         System.out.println("read : " + string);60                         //调用 主线程 广播61                         Server.send(string);62                     }63                 }64             }65             66         } catch (IOException e) {67             // TODO: handle exception68             System.out.println("异常2");69         }70     }71     72 }

*** 最后是 客户端代码 ***

  1 package socket多客户端;  2   3 import java.io.*;  4 import java.net.*;  5 import java.util.Scanner;  6   7 public class Client {  8       9      10     private static Socket socket; 11     private static BufferedReader bufferedReader; 12     private static PrintStream printStream; 13      14     //  将 读服务端数据封装在 Client—read 方法里 15     public static void Client_read(Socket socket){ 16         // 匿名内部类 开 一个子线程 17         new Thread(new Runnable() { 18             private BufferedReader bufferedReader_ec; 19              20             @Override 21             public void run() { 22                 // TODO Auto-generated method stub 23                  24                 try { 25                     bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 26                     String str = bufferedReader.readLine(); 27                     if("".equals(str) || str == null || "end".equals(str)){ 28                          29                     }else{ 30                         System.out.println(str); 31                     } 32                      33                 } catch (Exception e) { 34                     // TODO: handle exception 35                 } 36             } 37         }).start(); 38     } 39      40     //  Get_Set 方法 处理 客户端与服务端 数据的读写 41     static void Get_Set(Socket socket){ 42          43         try { 44             bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 45             printStream = new PrintStream(socket.getOutputStream()); 46             Scanner keyboard = new Scanner(System.in); 47              48             Boolean flag = true; 49             while(flag){ 50                  51                 // 在这里调用 之前封装的 Client_read 方法 52                 Client_read(socket); 53          54                 //  从 键盘 输入数据 55                 String shuru = keyboard.nextLine(); 56                 if("".equals(shuru) || shuru == null){  
 57                     flag = false;                     //  通过 嵌套if else  筛掉无用值 58                 }else{ 59                     if("end".equals(shuru)){ 60                         flag = false; 61                     }else{ 62                         printStream.println(shuru);    // 发送至服务端 63                         printStream.flush(); 64                     } 65                 } 66                  67                  68             } 69              70              71         } catch (Exception e) { 72             // TODO: handle exception 73         } 74          75          76     } 77      78     public static void main(String[] args) { 79          80         try { 81              82             socket = new Socket("localhost",6789); 83             System.out.println("客户端已连接至服务端!"); 84             Get_Set(socket); 85              86         } catch (Exception e) { 87             // TODO: handle exception 88             System.out.println("客户端异常1"); 89         }finally { 90             try { 91                 printStream.close(); 92                 bufferedReader.close(); 93                 socket.close(); 94                  95             } catch (Exception e2) { 96                 // TODO: handle exception 97                 System.out.println("客户端异常2"); 98             } 99         }100         101         102     }103     104 105 }

 

好了 ,下面我们来运行 看看结结果。

第一个控制台是 服务端

第二个控制台是 客户端1

第三个控制台是 客户端2

 

 

 

这样我们就实现了 一个简单的基于TCP/IP协议的socket多客户端通信。



本文转自 sshpp 51CTO博客,原文链接:http://blog.51cto.com/12902932/1925685,如需转载请自行联系原作者

相关文章
|
2月前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
本系列教程笔记详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。若需快速学习Kotlin,建议查看“简洁”系列教程。本期重点介绍了Kotlin与Java的共存方式,包括属性、单例对象、默认参数方法、包方法、扩展方法以及内部类和成员的互操作性。通过这些内容,帮助你在项目中更好地结合使用这两种语言。
45 1
|
2月前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
34 2
|
1天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
2月前
|
Java 调度
[Java]线程生命周期与线程通信
本文详细探讨了线程生命周期与线程通信。文章首先分析了线程的五个基本状态及其转换过程,结合JDK1.8版本的特点进行了深入讲解。接着,通过多个实例介绍了线程通信的几种实现方式,包括使用`volatile`关键字、`Object`类的`wait()`和`notify()`方法、`CountDownLatch`、`ReentrantLock`结合`Condition`以及`LockSupport`等工具。全文旨在帮助读者理解线程管理的核心概念和技术细节。
38 1
[Java]线程生命周期与线程通信
|
20天前
|
Java
JAVA多线程通信:为何wait()与notify()如此重要?
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是实现线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件满足时被唤醒,从而确保数据一致性和同步。相比其他通信方式,如忙等待,这些方法更高效灵活。 示例代码展示了如何在生产者-消费者模型中使用这些方法实现线程间的协调和同步。
32 3
|
2月前
|
存储 消息中间件 安全
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
【10月更文挑战第9天】本文介绍了如何利用JUC组件实现Java服务与硬件通过MQTT的同步通信(RRPC)。通过模拟MQTT通信流程,使用`LinkedBlockingQueue`作为消息队列,详细讲解了消息发送、接收及响应的同步处理机制,包括任务超时处理和内存泄漏的预防措施。文中还提供了具体的类设计和方法实现,帮助理解同步通信的内部工作原理。
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
|
27天前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
27天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
27天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
|
13天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
10 0