JAVA-Socket通信笔记

Posted 昕无旁骛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA-Socket通信笔记相关的知识,希望对你有一定的参考价值。

JAVA - Socket

 

  从开学到现在 也学了三个月时间的java了,一直在 在 语法和基本使用上周旋,井底之娃一枚。 这两天 有学长指点,花了两天的时间 学习了java多线程和socket的简单使用,利用周末时间 自己写了个 Socket 多客户端的 Demo,有很多不成熟或者不好的 地方,请指正。

 

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 exception
48             System.out.println("服务端异常1");
49         }finally {
50             
51             try {
52                 socket.close();
53                 serverSocket.close();
54                 
55             } catch (IOException e2) {
56                 // TODO: handle exception
57                 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     @Override
23     public void run() {
24         // TODO Auto-generated method stub
25         super.run();
26         
27         try {
28             Get_Set(socket);
29             
30         } catch (Exception e) {
31             // TODO: handle exception
32             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 exception
68             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多客户端通信。

笔者 还是个 编程菜鸟,有什么不好的地方,希望各位大牛可以指正。

以上是关于JAVA-Socket通信笔记的主要内容,如果未能解决你的问题,请参考以下文章

java-Socket

JAVA-socket.io中常用注解的作用

在tablayout片段之间进行通信[重复]

与另一个片段通信的片段接口

学习笔记:python3,代码片段(2017)

无法通过接口获取与片段通信的活动