通过 Socket 实现 TCP 编程

一、Socket简介

Socket通信实现步骤

1.创建ServerSocket和Socket

2.打开连接到Socket的输入/输出流

3.按照协议对Socket进行读/写操作

4.关闭输入输出流、关闭Socket

二、编程实现基于TCP的Socket通信之服务端与客户端

服务器端:

1.创建ServerSocket对象,绑定监听端口

2.通过accept()方法监听客户端请求

3.连接建立后,通过输入流读取客户端发送的请求信息

4.通过输出流向客户端响应信息

5.关闭相关资源

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStream;
 4 import java.io.InputStreamReader;
 5 import java.net.ServerSocket;
 6 import java.net.Socket;
 7 
 8 /*
 9  * 基于TCP协议的Socket通信,实现用户登陆
10  * 服务器端
11  */
12 public class Server {
13     public static void main(String[] args) {
14         try {
15             //1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
16             ServerSocket serverSocket = new ServerSocket(8888);
17             //2.调用accept()方法开始监听,等待客户端的连接
18             System.out.println("***服务器即将启动,等待客户端的连接***");
19             Socket socket = serverSocket.accept();
20             //3.获取输入流,并读取客户端信息
21             InputStream is = socket.getInputStream();//字节输入流
22             InputStreamReader isr = new InputStreamReader(is);//将字节流转换为字符流
23             BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲
24             String info = null;
25             while((info=br.readLine())!=null) {//循环读取客户端的信息
26                 System.out.println("我是服务器,客户端说:" + info);
27             }
28             socket.shutdownInput();//关闭输入流
29             
30             //4.关闭资源
31             br.close();
32             isr.close();
33             is.close();
34             socket.close();
35             serverSocket.close();        
36         } catch (IOException e) {
37             // TODO Auto-generated catch block
38             e.printStackTrace();
39         }
40         
41     }
42 
43 }

客户端:

1.创建Socket对象,指明需要连接的服务器的地址和端口号

2.连接建立后,通过输出流向服务器发送请求信息

3.通过输入流获取服务器响应的信息

4.关闭相应资源

 1 import java.io.IOException;
 2 import java.io.OutputStream;
 3 import java.io.PrintWriter;
 4 import java.net.Socket;
 5 import java.net.UnknownHostException;
 6 
 7 /*
 8  * 客户端
 9  */
10 public class Client {
11     public static void main(String[] args) {
12         try {
13             //1.创建客户端Socket,指定服务器地址和端口
14             Socket socket = new Socket("localhost",8888);
15             //2.获取输出流,向服务器端发送信息
16             OutputStream os = socket.getOutputStream();//字节输出流
17             PrintWriter pw = new PrintWriter(os);
18             pw.write("用户名:admin;密码:123");
19             pw.flush();
20             socket.shutdownOutput();//关闭输出流
21             
22             //3.关闭资源
23             pw.close();
24             os.close();
25             socket.close();
26         } catch (UnknownHostException e) {
27             e.printStackTrace();
28         } catch (IOException e) {
29             e.printStackTrace();
30         }
31     }
32 }

三、完善用户登陆之服务器响应客户端

服务端:

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStream;
 4 import java.io.InputStreamReader;
 5 import java.io.OutputStream;
 6 import java.io.PrintWriter;
 7 import java.net.ServerSocket;
 8 import java.net.Socket;
 9 
10 /*
11  * 基于TCP协议的Socket通信,实现用户登陆
12  * 服务器端(需要早于客户端启动)
13  */
14 public class Server {
15     public static void main(String[] args) {
16         try {
17             //1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
18             ServerSocket serverSocket = new ServerSocket(8888);
19             //2.调用accept()方法开始监听,等待客户端的连接
20             System.out.println("***服务器即将启动,等待客户端的连接***");
21             Socket socket = serverSocket.accept();
22             //3.获取输入流,并读取客户端信息
23             InputStream is = socket.getInputStream();//字节输入流
24             InputStreamReader isr = new InputStreamReader(is);//将字节流转换为字符流
25             BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲
26             String info = null;
27             while((info=br.readLine())!=null) {//循环读取客户端的信息
28                 System.out.println("我是服务器,客户端说:" + info);
29             }
30             socket.shutdownInput();//关闭输入流
31             
32             //4.获取输出流,响应客户端的请求
33             OutputStream os = socket.getOutputStream();
34             PrintWriter pw = new PrintWriter(os);//包装为打印流
35             pw.write("欢迎您!");
36             pw.flush();//调用flush()方法将缓冲输出
37             
38             //5.关闭资源
39             pw.close();
40             os.close();
41             br.close();
42             isr.close();
43             is.close();
44             socket.close();
45             serverSocket.close();        
46         } catch (IOException e) {
47             // TODO Auto-generated catch block
48             e.printStackTrace();
49         }
50         
51     }
52 
53 }

客户端:

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStream;
 4 import java.io.InputStreamReader;
 5 import java.io.OutputStream;
 6 import java.io.PrintWriter;
 7 import java.net.ServerSocket;
 8 import java.net.Socket;
 9 
10 /*
11  * 基于TCP协议的Socket通信,实现用户登陆
12  * 服务器端(需要早于客户端启动)
13  */
14 public class Server {
15     public static void main(String[] args) {
16         try {
17             //1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
18             ServerSocket serverSocket = new ServerSocket(8888);
19             //2.调用accept()方法开始监听,等待客户端的连接
20             System.out.println("***服务器即将启动,等待客户端的连接***");
21             Socket socket = serverSocket.accept();
22             //3.获取输入流,并读取客户端信息
23             InputStream is = socket.getInputStream();//字节输入流
24             InputStreamReader isr = new InputStreamReader(is);//将字节流转换为字符流
25             BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲
26             String info = null;
27             while((info=br.readLine())!=null) {//循环读取客户端的信息
28                 System.out.println("我是服务器,客户端说:" + info);
29             }
30             socket.shutdownInput();//关闭输入流
31             
32             //4.获取输出流,响应客户端的请求
33             OutputStream os = socket.getOutputStream();
34             PrintWriter pw = new PrintWriter(os);//包装为打印流
35             pw.write("欢迎您!");
36             pw.flush();//调用flush()方法将缓冲输出
37             
38             //5.关闭资源
39             pw.close();
40             os.close();
41             br.close();
42             isr.close();
43             is.close();
44             socket.close();
45             serverSocket.close();        
46         } catch (IOException e) {
47             // TODO Auto-generated catch block
48             e.printStackTrace();
49         }
50         
51     }
52 
53 }

四、使用多线程实现多客户端的通信

应用多线程来实现服务器与多客户端之间的通信

基本步骤:

1.服务器端创建ServerSocket,循环调用accept()等待客户端连接

2.客户端创建一个socket并请求和服务器端连接

3.服务器端接受客户端请求,创建socket与该客户建立专线连接

4.建立连接的两个socket在一个单独的线程上对话

5.服务器端继续等待新的连接

服务器线程处理类:

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStream;
 4 import java.io.InputStreamReader;
 5 import java.io.OutputStream;
 6 import java.io.PrintWriter;
 7 import java.net.Socket;
 8 
 9 /*
10  * 服务器线程处理类
11  */
12 public class ServerThread extends Thread {
13     // 和本线程相关的Socket
14     Socket socket = null;
15 
16     public ServerThread(Socket socket) {
17         this.socket = socket;
18     }
19     
20     //线程执行的操作,响应客户端的请求
21     public void run(){
22         InputStream is=null;
23         InputStreamReader isr=null;
24         BufferedReader br=null;
25         OutputStream os=null;
26         PrintWriter pw=null;
27         try {
28             //获取输入流,并读取客户端信息
29             is = socket.getInputStream();
30             isr = new InputStreamReader(is);
31             br = new BufferedReader(isr);
32             String info=null;
33             while((info=br.readLine())!=null){//循环读取客户端的信息
34                 System.out.println("我是服务器,客户端说:"+info);
35             }
36             socket.shutdownInput();//关闭输入流
37             //获取输出流,响应客户端的请求
38             os = socket.getOutputStream();
39             pw = new PrintWriter(os);
40             pw.write("欢迎您!");
41             pw.flush();//调用flush()方法将缓冲输出
42         } catch (IOException e) {
43             e.printStackTrace();
44         }finally{
45             //关闭资源
46             try {
47                 if(pw!=null)
48                     pw.close();
49                 if(os!=null)
50                     os.close();
51                 if(br!=null)
52                     br.close();
53                 if(isr!=null)
54                     isr.close();
55                 if(is!=null)
56                     is.close();
57                 if(socket!=null)
58                     socket.close();
59             } catch (IOException e) {
60                 e.printStackTrace();
61             }
62         }
63     }
64 }

修改服务器端:

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStream;
 4 import java.io.InputStreamReader;
 5 import java.io.OutputStream;
 6 import java.io.PrintWriter;
 7 import java.net.InetAddress;
 8 import java.net.ServerSocket;
 9 import java.net.Socket;
10 
11 /*
12  * 基于TCP协议的Socket通信,实现用户登陆
13  * 服务器端(需要早于客户端启动)
14  */
15 public class Server {
16     public static void main(String[] args) {
17         try {
18             //1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
19             ServerSocket serverSocket = new ServerSocket(8888);
20             
21             Socket socket = null;
22             //记录客户端的数量
23             int count = 0;
24             System.out.println("***服务器即将启动,等待客户端的连接***");
25             //循环监听等待客户端的连接
26             while (true) {
27                 //2.调用accept()方法开始监听,等待客户端的连接
28                 socket = serverSocket.accept();
29                 //创建一个新的线程
30                 ServerThread serverThread = new ServerThread(socket);
31                 //启动线程
32                 serverThread.start();
33                 
34                 count++;//统计客户端的数量
35                 System.out.println("输出客户端的数量:" + count);
36                 InetAddress address = socket.getInetAddress();
37                 System.out.println("当前客户端的IP:" + address.getHostAddress());
38             }
39             
40             
41             
42                         
43             /*
44             //3.获取输入流,并读取客户端信息
45             InputStream is = socket.getInputStream();//字节输入流
46             InputStreamReader isr = new InputStreamReader(is);//将字节流转换为字符流
47             BufferedReader br = new BufferedReader(isr);//为输入流添加缓冲
48             String info = null;
49             while((info=br.readLine())!=null) {//循环读取客户端的信息
50                 System.out.println("我是服务器,客户端说:" + info);
51             }
52             socket.shutdownInput();//关闭输入流
53             
54             //4.获取输出流,响应客户端的请求
55             OutputStream os = socket.getOutputStream();
56             PrintWriter pw = new PrintWriter(os);//包装为打印流
57             pw.write("欢迎您!");
58             pw.flush();//调用flush()方法将缓冲输出
59             
60             //5.关闭资源
61             pw.close();
62             os.close();
63             br.close();
64             isr.close();
65             is.close();
66             socket.close();
67             */
68             
69             
70             //serverSocket.close();
71             
72         } catch (IOException e) {
73             // TODO Auto-generated catch block
74             e.printStackTrace();
75         }
76         
77     }
78 
79 }

修改客户端:

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStream;
 4 import java.io.InputStreamReader;
 5 import java.io.OutputStream;
 6 import java.io.PrintWriter;
 7 import java.net.Socket;
 8 import java.net.UnknownHostException;
 9 
10 /*
11  * 客户端
12  */
13 public class Client {
14     public static void main(String[] args) {
15         try {
16             //1.创建客户端Socket,指定服务器地址和端口
17             Socket socket = new Socket("localhost",8888);
18             //2.获取输出流,向服务器端发送信息
19             OutputStream os = socket.getOutputStream();//字节输出流
20             PrintWriter pw = new PrintWriter(os);
21             pw.write("用户名:admin;密码:123");
22             pw.flush();
23             socket.shutdownOutput();//关闭输出流
24             
25             //3.获取输入流,并读取服务器端的响应信息
26             InputStream is = socket.getInputStream();//字节输入流
27             BufferedReader br = new BufferedReader(
28                     new InputStreamReader(is));//将字节流转换为字符流,为输入流添加缓冲
29             String info = null;
30             while((info=br.readLine())!=null) {//循环读取客户端的信息
31                 System.out.println("我是客户端,服务器说:" + info);
32             }
33             
34             //4.关闭资源
35             br.close();
36             is.close();
37             pw.close();
38             os.close();
39             socket.close();
40         } catch (UnknownHostException e) {
41             e.printStackTrace();
42         } catch (IOException e) {
43             e.printStackTrace();
44         }
45     }
46 }

 

posted @ 2019-03-31 16:42  丿Joy  阅读(2102)  评论(0编辑  收藏  举报