通过 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 }