首页 > 代码库 > Socket编程(三)★

Socket编程(三)★

★Sockets 使用TCP协议实现网络通信的Socket相关类(重点)

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议

服务器端的ServerSocket类        客户端的Socket类

 

①.服务器端通信流程                                                           ②. 客户端通信流程

   1. 创建ServerSocket对象,绑定该程序使用的端口                  1. 创建Socket对象,指明服务器的IP地址和通信程序的端口号                              

   2. 建立accept()方法监听客户端请求                                     2.  建立链接后,通过输出流向服务器发送请求连接。

   3. 建立连接后,通过输入流读取客户端放送的请求信息               3. 通过输入流获得服务器的响应信息。

   4. 通过输出流向客户端发送响应信息                                          4. 重复2,3

   5. 重复3,4                                                                              5. 关闭相关资源

   6. 关闭相关资源

 

注意: 我的示例代码客户端和服务器都是本机

 

一. TCP基础的C/S通信

     示例代码省略了客户端重复发送请求的步骤

     示例代码:

   服务器端

 1 public static void main(String[] args) {
 2         try {
 3             //1.创建一个服务器端Socket,即ServerSicket,指定绑定端口,并监听此端口
 4             ServerSocket serverSocket = new ServerSocket(888);
 5             System.out.println("***服务器即将启动,等待客户端的连接***");
 6             //2.通过accept()方法监听客户端请求,若接到请求服务器会返回一个socket对象进行通信
 7             Socket socket = serverSocket.accept();
 8             //3.建立连接后,通过输入流读取客户端发送的信息
 9             InputStream is = socket.getInputStream();//获取资源的字节输入流
10             InputStreamReader isr = new InputStreamReader(is);//字节输入流转字符输入流
11             BufferedReader buffer = new BufferedReader(isr);//为字符输入流添加缓冲
12             String info = null;
13             while((info = buffer.readLine()) != null){
14                 System.out.println("客户端发送的信息:" + "\n" + info + "\n");
15             }
16             socket.shutdownInput();//关闭输入流
17             //4.通过输出流向客户端放送相应信息
18             OutputStream os = socket.getOutputStream();//获取字节输出流
19             PrintWriter pw = new PrintWriter(os);//将输出流打包为打印流
20             pw.write("欢迎您!\n");
21             pw.flush();//刷新
22             socket.shutdownOutput();//关闭输出流
23             //5.关闭资源
24             pw.close();
25             os.close();
26             buffer.close();
27             isr.close();
28             is.close();
29             socket.close();
30             serverSocket.close();
31         } catch (IOException e) {
32             e.printStackTrace();
33         }
34     }

      客户端:

 1 public static void main(String[] args) {
 2         try {
 3             //1.创建Socket对象,指明需要连接的服务器地址和端口号
 4             Socket socket = new Socket("localhost",888);
 5             //2.链接后通过输出流向服务器端放送请求信息
 6             OutputStream os = socket.getOutputStream();
 7             PrintWriter pw = new PrintWriter(os);
 8             pw.write("用户名:admin;密码:4399");
 9             pw.flush();//刷新
10             socket.shutdownOutput();//关闭输出流
11             //3.通过输出流获取服务器响应的信息
12             InputStream is = socket.getInputStream();
13             InputStreamReader isr = new InputStreamReader(is);
14             BufferedReader buffer = new BufferedReader(isr);
15             String info = null;
16             while((info = buffer.readLine()) != null){
17                 System.out.println(info);
18             }
19             socket.shutdownInput();//关闭输入流
20             //4.关闭相关资源
21             buffer.close();
22             isr.close();
23             is.close();
24             pw.close();
25             os.close();
26             socket.close();
27         } catch (UnknownHostException e) {
28             e.printStackTrace();
29         } catch (IOException e) {
30             e.printStackTrace();
31         }
32     }

输出结果

1.开始。服务器端:

***服务器即将启动,等待客户端的连接***

服务器运行带accept()方法,处于阻塞状态,等待客户端发送信息响应连接

2.建立链接后。服务器端:                          客户端:

***服务器即将启动,等待客户端的连接***                   欢迎您!
客户端发送的信息:
用户名:admin;密码:4399

      

实际就是ServerSocket的accept()方法监测到客户端的请求之后生成一个服务器的Scoket对象

实际就是两个Scoket对象在进行通信   Socket = IP地址 + 端口号

 

二. 进阶版,多线程TCP的C/S通信

      上诉例子只实现了一台服务器和一台客户机的通信,但实际情况通常都是一台服务器对应多个客户端的情况,要解决这个方法,我们引用了线程。

      示例代码:(客户端代码不变)

      客户端:

 1 public static void main(String[] args) {
 2         try {
 3             //创建一个服务器端Socket,即ServerSicket,指定绑定端口,并监听此端口
 4             ServerSocket serverSocket = new ServerSocket(888);
 5             System.out.println("***服务器即将启动,等待客户端的连接***");
 6             Socket socket = null;
 7             //通过accept()方法循环监听客户端请求,若接到请求服务器会返回一个socket对象进行通信
 8             while(true){
 9                  socket = serverSocket.accept();
10                  ServerThread serverThread = new ServerThread(socket);
11                  serverThread.start();
12                  System.out.println("客户端" + socket.getInetAddress().getHostAddress() + "说:");
13             }
14         } catch (IOException e) {
15             e.printStackTrace();
16         }
17     }
 1 public class ServerThread extends Thread {
 2 
 3     Socket socket = null;
 4     
 5     public ServerThread(Socket socket){
 6         this.socket = socket;
 7     }
 8     
 9     public void run(){
10         InputStream is = null;
11         InputStreamReader isr = null;
12         BufferedReader buffer = null;
13         OutputStream os = null;
14         PrintWriter pw = null;
15         try {
16             //建立连接后,通过输入流读取客户端发送的信息
17             is = socket.getInputStream();
18             isr = new InputStreamReader(is);
19             buffer = new BufferedReader(isr);
20             String info = null;
21             while((info = buffer.readLine()) != null){
22                 System.out.println( info + "\n");
23             }
24             socket.shutdownInput();//关闭输入流
25             //通过输出流向客户端放送相应信息
26             os = socket.getOutputStream();
27             pw = new PrintWriter(os);
28             pw.write("欢迎您!\n");
29             pw.flush();//刷新
30             socket.shutdownOutput();//关闭输出流
31         } catch (IOException e) {
32             e.printStackTrace();
33         } finally{
34             //关闭资源
35             try {
36                 if(pw != null)
37                     pw.close();
38                 if(os != null)
39                     os.close();
40                 if(buffer != null)
41                     buffer.close();
42                 if(isr != null)
43                     isr.close();
44                 if(is != null)
45                     is.close();
46                 if(socket != null)
47                     socket.close();
48             } catch (IOException e) {
49                 // TODO Auto-generated catch block
50                 e.printStackTrace();
51             }
52         }
53     }
54 }

运行结果:

***服务器即将启动,等待客户端的连接***
客户端127.0.0.1说:
用户名:admin;密码:4399

客户端127.0.0.1说:
用户名:xiaolai;密码:1104

这里其实是有两个客户端与服务器进行了响应,因为两个客户端都是我的本机,所以IP地址会相同。

 

运用一个死循环执行accept()语句。

只要有客户端发送请求,服务器就会生成一个Socket对象,开启线程与一个客户端通信,

多个客户端发送请求,服务器就会不停的切换生成Socket对象,并开启线程进行通信

从而实现了一个服务器通过多线程的方法与数台客户机通信。

 

 如果有什么错误,或者我理解错误或不当的,恳请大家纠正,谢谢!嘻嘻嘻~

Socket编程(三)★