1.服务端单线程:

Server端:

 1 package socket.demo.singlethread;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.InputStream;
 5 import java.io.InputStreamReader;
 6 import java.net.ServerSocket;
 7 import java.net.Socket;
 8 
 9 public class Server {
10     public static void main(String[] args) {
11         try {
12             //1.定义一个ServerSocket对象进行服务端的端口注册
13             ServerSocket serverSocket = new ServerSocket(9999);
14 
15             //2.监听客户端的sokcet链接请求
16             Socket socket = serverSocket.accept();
17 
18             //3.从客户端得到一个字节输入流对象
19             InputStream inputStream = socket.getInputStream();
20 
21             //4.把字节输入流包装成缓冲字节输入流
22             //BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
23 
24             //4.把字节输入流包装成缓冲字节输入流
25             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
26             String msg;
27             while ((msg = bufferedReader.readLine()) != null) {
28                 System.out.println("服务端接收到:" + msg);
29             }
30         } catch (Exception e) {
31             e.printStackTrace();
32         }
33     }
34 }

Client端:

 1 package socket.demo.singlethread;
 2 
 3 import java.io.IOException;
 4 import java.io.OutputStream;
 5 import java.io.PrintStream;
 6 import java.net.Socket;
 7 
 8 public class Client {
 9     public static void main(String[] args) throws IOException {
10         //1.创建Sokcet对象请求服务端
11         Socket socket = new Socket("127.0.0.1", 9999);
12 
13         //2.从Socket对象中获取一个字节输出流
14         OutputStream outputStream = socket.getOutputStream();
15 
16         //3.把字节输出流包装成打印流
17         PrintStream printStream = new PrintStream(outputStream);
18 
19         //打印
20         printStream.println("hello world");
21 
22         //刷新
23         printStream.flush();
24     }
25 }

 

2.服务端多线程

Server端:

 1 package socket.demo.multithread;
 2 
 3 import java.net.ServerSocket;
 4 import java.net.Socket;
 5 
 6 public class Server {
 7     public static void main(String[] args) throws Exception {
 8         ServerSocket serverSocket = new ServerSocket(9999);
 9         while (true) {
10             Socket socket = serverSocket.accept();
11             new ServerThreadReader(socket).start();
12         }
13     }
14 }

线程类:

 1 package socket.demo.multithread;
 2 
 3 
 4 import java.io.BufferedReader;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.io.InputStreamReader;
 8 import java.net.Socket;
 9 
10 public class ServerThreadReader extends Thread {
11     private Socket socket;
12 
13     public ServerThreadReader(Socket socket) {
14         this.socket = socket;
15     }
16 
17     @Override
18     public void run() {
19         try {
20             InputStream inputStream = this.socket.getInputStream();
21             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
22             String msg;
23             while ((msg = bufferedReader.readLine()) != null) {
24                 System.out.println(msg);
25             }
26 
27         } catch (IOException e) {
28             e.printStackTrace();
29         }
30     }
31 }

Client端:

 1 package socket.demo.multithread;
 2 
 3 import java.io.PrintStream;
 4 import java.net.Socket;
 5 import java.util.Scanner;
 6 
 7 public class Client {
 8     public static void main(String[] args) throws Exception {
 9         Socket socket = new Socket("127.0.0.1", 9999);
10         PrintStream printStream = new PrintStream(socket.getOutputStream());
11         Scanner scanner = new Scanner(System.in);
12         while (true) {
13             System.out.print("请输入:");
14             String msg = scanner.nextLine();
15             printStream.println(msg);
16             printStream.flush();
17         }
18     }
19 }

 

3.使用线程池实现伪异步IO通信

Server端:

 1 public class Server {
 2     public static void main(String[] args) {
 3         try{
 4             //1、注册端口
 5             ServerSocket ss = new ServerSocket(9999);
 6 
 7             //2、定义一个循环接受客户端的连接请求
 8             //maxThreadNum:最大线程数量
 9             //queueSize:任务数量
10             HandlerSocketServerPool pool = new HandlerSocketServerPool(6,10);
11             while(true){
12                 Socket socket = ss.accept();
13                 //3、把socket对象交给线程池进行处理
14                 Runnable target =  new ServerRunnableTarget(socket);
15                 pool.execute(target);
16             }
17         }
18         catch (Exception e){
19             e.printStackTrace();
20         }
21     }
22 }

 

线程控制类:

 1 public class HandlerSocketServerPool{
 2     //1、创建一个线程池变量,用来存储线程池对象
 3     private ExecutorService executorService;
 4 
 5     public HandlerSocketServerPool(int maxThreadNum,int queueSize){
 6         executorService = new ThreadPoolExecutor(3,maxThreadNum,120,TimeUnit.SECONDS,new ArrayBlockingQueue<>(queueSize));
 7     }
 8 
 9     public void execute(Runnable target){
10         executorService.execute(target);
11     }
12 }

 

线程任务类:

 1 public class ServerRunnableTarget implements Runnable {
 2     Socket socket;
 3 
 4     public ServerRunnableTarget(Socket socket){
 5         this.socket = socket;
 6     }
 7 
 8     @Override
 9     public void run() {
10         //这里是从socket中获取输入流,并进行打印的逻辑
11         InputStream inputStream = null;
12         try {
13             inputStream = this.socket.getInputStream();
14             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
15             String msg;
16             while (true) {
17                 if (!((msg = bufferedReader.readLine()) != null)) break;
18                 System.out.println(msg);
19             }
20         } catch (IOException e) {
21             e.printStackTrace();
22         }
23     }
24 }

 

客户端:

 1 public class Client {
 2     public static void main(String[] args) throws IOException {
 3         Socket socket = new Socket("127.0.0.1", 9999);
 4         PrintStream printStream = new PrintStream(socket.getOutputStream());
 5         Scanner scanner = new Scanner(System.in);
 6         while (true) {
 7             System.out.print("请输入:");
 8             String msg = scanner.nextLine();
 9             printStream.println(msg);
10             printStream.flush();
11         }
12     }
13 }

 

4.实现文件上传功能:

Server端:

 1 public class Server {
 2     public static void main(String[] args) {
 3         try {
 4             ServerSocket ss = new ServerSocket(9999);
 5             while (true) {
 6                 Socket socket = ss.accept();
 7                 ServerReaderThread serverReaderThread = new ServerReaderThread(socket);
 8                 serverReaderThread.start();
 9             }
10         } catch (Exception e) {
11             e.printStackTrace();
12         }
13     }
14 }

 

线程处理类:

 1 public class ServerReaderThread extends Thread {
 2     private Socket socket;
 3 
 4     public ServerReaderThread(Socket socket) {
 5         this.socket = socket;
 6     }
 7 
 8     @Override
 9     public void run() {
10         try {
11             DataInputStream dis = new DataInputStream(socket.getInputStream());
12             String suffix = dis.readUTF();//读取后缀
13             System.out.println("服务端已经成功接受到了文件类型:" + suffix);
14             FileOutputStream fileOutputStream = new FileOutputStream("D:\\" + UUID.randomUUID().toString() + suffix);
15             byte[] buffer = new byte[1024];
16             int len = 0;
17             while ((len = dis.read(buffer)) > 0) {
18                 fileOutputStream.write(buffer, 0, len);
19                 fileOutputStream.flush();
20             }
21             fileOutputStream.close();
22             System.out.println("服务端文件保存成功");
23         } catch (Exception e) {
24             e.printStackTrace();
25         }
26     }
27 }

 

Client端:

 1 public class Client {
 2     public static void main(String[] args) {
 3         try {
 4             //1、请求与服务端的Socket连接
 5             Socket socket = new Socket("127.0.0.1", 9999);
 6             //2、把字节输出流包装成一个数据输出流
 7             DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
 8             //3、先发送上传文件的后缀到服务端
 9             dos.writeUTF(".txt");
10 
11             InputStream is = new FileInputStream("D:\\1.txt");
12             byte[] buffer = new byte[1024];
13             int len;
14             while ((len = is.read(buffer)) > 0) {
15                 dos.write(buffer, 0, len);
16             }
17             dos.flush();
18             is.close();
19             socket.shutdownOutput();//通知服务端,数据已经发送完毕
20         } catch (Exception e) {
21             e.printStackTrace();
22         }
23     }
24 }

 

 

补充C#版本服务端多线程,和Java的对比一下:

Server端:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Net.Sockets;
 6 using System.Net;
 7 using System.Threading;
 8 
 9 namespace ServerSocket
10 {
11     class Program
12     {
13         private static byte[] m_DataBuffer = new byte[1024];
14         //设置端口号
15         private static int m_Port = 8099;
16         static Socket serverSocket;
17         static void Main(string[] args)
18         {
19             //为了方便在本机上同时运行Client和server,使用回环地址为服务的监听地址
20             IPAddress ip = IPAddress.Loopback;
21             //实例化一个Socket对象,确定网络类型、Socket类型、协议类型
22             serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
23             //Socket对象绑定IP和端口号
24             serverSocket.Bind(new IPEndPoint(ip, m_Port));
25             //挂起连接队列的最大长度为15,启动监听
26             serverSocket.Listen(15);
27 
28             Console.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());
29             //一个客户端连接服务器时创建一个新的线程
30             Thread myThread = new Thread(ListenClientConnect);
31             myThread.Start();
32         }
33 
34         /// <summary>
35         /// 接收连接
36         /// </summary>
37         private static void ListenClientConnect()
38         {
39             while (true)
40             {
41                 //运行到Accept()方法是会阻塞程序(同步Socket),
42                 //收到客户端请求创建一个新的Socket Client对象继续执行
43                 Socket clientSocket = serverSocket.Accept();
44                 clientSocket.Send(Encoding.UTF8.GetBytes("Server说:Client 你好!"));
45                 //创建一个接受客户端发送消息的线程
46                 Thread reciveThread = new Thread(ReciveMessage);
47                 reciveThread.Start(clientSocket);
48             }
49         }
50           
51         /// <summary>
52         /// 接收信息
53         /// </summary>
54         /// <param name="clientSocket">包含客户端信息的套接字</param>
55         private static void ReciveMessage(Object clientSocket)
56         {
57             if (clientSocket != null)
58             {
59                 Socket m_ClientSocket = clientSocket as Socket;
60                 while (true)
61                 {
62                     try
63                     {
64                         //通过clientSocket接收数据
65                         int reciverNumber = m_ClientSocket.Receive(m_DataBuffer);
66                         if (reciverNumber == 0)
67                         {
68                             m_ClientSocket.Shutdown(SocketShutdown.Both);
69                             m_ClientSocket.Close();
70                             Console.WriteLine("客户端连接已断开");
71                             break;
72                         }
73                         Console.WriteLine("接收客户端:{0}消息:{1}", m_ClientSocket.RemoteEndPoint.ToString(), Encoding.UTF8.GetString(m_DataBuffer, 0, reciverNumber));
74                     }
75                     catch (Exception ex)
76                     {
77                         Console.WriteLine(ex.Message);
78                         m_ClientSocket.Shutdown(SocketShutdown.Both);
79                         m_ClientSocket.Close();
80                         break;
81                     }
82                 }
83             }
84         }
85     }
86 }

Client端:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Net.Sockets;
 6 using System.Net;
 7 using System.Threading;
 8 
 9 namespace ClientSocket
10 {
11     class Program
12     {
13         //创建一个数据缓冲区
14         private static byte[] m_DataBuffer = new byte[1024];
15         static void Main(string[] args)
16         {
17             IPAddress ip = IPAddress.Loopback;
18             Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
19 
20             try
21             {
22                 clientSocket.Connect(new IPEndPoint(ip, 8099));
23                 Console.WriteLine("连接服务器成功");
24             }
25             catch (Exception ex)
26             {
27                 Console.WriteLine("连接服务器失败,按回车键退出");
28                 Console.WriteLine(ex.Message);
29                 return;
30             }
31             //通过clientSocket接收数据
32             int receiveLength = clientSocket.Receive(m_DataBuffer);
33             Console.WriteLine("接受服务器消息:{0}", Encoding.UTF8.GetString(m_DataBuffer, 0, receiveLength));
34             //通过clientSocket发送数据
35             for (int i = 0; i < 10; i++)
36             {
37                 try
38                 {
39                     Thread.Sleep(1000);
40                     string sendMessage = string.Format("{0} {1}", "Server 你好!", DateTime.Now.ToString());
41                     clientSocket.Send(Encoding.UTF8.GetBytes(sendMessage));
42                     Console.WriteLine("向服务器发送消息:{0}", sendMessage);
43                 }
44                 catch
45                 {
46                     clientSocket.Shutdown(SocketShutdown.Both);
47                     clientSocket.Close();
48                     break;
49                 }
50             }
51             Console.WriteLine("发送完毕,按回车键退出");
52             //发送完消息后关闭连接
53             clientSocket.Shutdown(SocketShutdown.Both);
54             clientSocket.Close();
55             Console.Read();
56         }
57     }
58 }

 

posted on 2020-12-19 16:59  Sempron2800+  阅读(88)  评论(0编辑  收藏  举报