上一篇文章说到怎样写一个最简单的Java Socket通信,但是在上一篇文章中的例子有一个问题就是Server只能接受一个Client请求,当第一个Client连接后就占据了这个位置,后续Client不能再继续连接,所以需要做些改动。
当Server每次接受到一个Client的请求之后,都建立一个线程,然后继续等待下一个Client的连接请求。这样就不会阻塞Server端接收请求了。具体代码如下:
代码流程图如下:
服务端的代码
public class MyServer1 implements Runnable { private Socket socket; private String clientId; public MyServer1(Socket socket) { this.socket = socket; } public static void main(String[] args) throws IOException { int port = 9999; // 监听服务器端口 ServerSocket server = new ServerSocket(port); System.out.println("listening on " + port); while(true) { Socket socket = server.accept(); new Thread(new MyServer1(socket)).start(); } } public void run() { // 设置客户端名称,方便区分不同client setClientId(); System.out.println("the client " + this.getClientId() + " has connected!"); // 获取客户端的输入流 BufferedReader in = null; PrintWriter out = null; try { in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 获取客户端的输出流 out = new PrintWriter(socket.getOutputStream()); while (true) { String msg = in.readLine(); System.out.println("----------------------------------------------------"); System.out.println("-------------client " + this.getClientId() + "--------------"); System.out.println("----------------------------------------------------"); System.out.println("\nServer received " + msg); if (msg.equals("bye")) { System.out.println("Server stoped!"); break; } else { // 向客户端发送信息 System.out.println("Server send " + msg + "\n"); out.print("Server responsed " + msg); out.flush(); } } } catch (IOException e) { e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e1) { e1.printStackTrace(); } } } public String getClientId() { return clientId; } public void setClientId() { Time now = new Time(new Date().getTime()); this.clientId = socket.getInetAddress().getHostAddress() + "-" + now.toString(); } }
客户端代码
public class MyClient { public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException { Scanner reader = new Scanner(System.in); // 创建客户端socket Socket client = new Socket("localhost", 9999); // 获取客户端的输出流(获取服务器端的输入流) PrintWriter out = new PrintWriter(client.getOutputStream()); // 获取客户端的输入流(获取服务器端的输出流) InputStream in = client.getInputStream(); while (true) { System.out.println("---------------------------"); System.out.println("Input Something: "); String msg = reader.nextLine(); System.out.println("Client sended " + msg); out.println(msg); out.flush(); Thread.sleep(1000); byte[] buff = new byte[in.available()]; in.read(buff); System.out.println(new String(buff, "UTF-8")); if (msg.equals("bye")) { System.out.println("Client stop!"); break; } } out.close(); client.close(); } }
先运行MyServer1类,再运行两个MyClient类(相当与两个线程)。结果如下所示:
clent1(127.0.0.1-16:22:53)
--------------------------- Input Something: 11 Client sended 11 Server responsed 11 --------------------------- Input Something: 123 Client sended 123 Server responsed 123 --------------------------- Input Something: bye Client sended bye Client stop!
client2(1127.0.0.1-16:22:59)
--------------------------- Input Something: 333 Client sended 333 Server responsed 333 --------------------------- Input Something: bye Client sended bye Client stop!
服务端
listening on 9999 the client 127.0.0.1-16:22:53 has connected! the client 127.0.0.1-16:22:59 has connected! ---------------------------------------------------- -------------client 127.0.0.1-16:22:59-------------- ---------------------------------------------------- Server received 333 Server send 333 ---------------------------------------------------- -------------client 127.0.0.1-16:22:53-------------- ---------------------------------------------------- Server received 11 Server send 11 ---------------------------------------------------- -------------client 127.0.0.1-16:22:53-------------- ---------------------------------------------------- Server received 123 Server send 123 ---------------------------------------------------- -------------client 127.0.0.1-16:22:53-------------- ---------------------------------------------------- Server received bye Server stoped! ---------------------------------------------------- -------------client 127.0.0.1-16:22:59-------------- ---------------------------------------------------- Server received bye Server stoped!
这种实现方式有以下不足之处
1、服务器创建和销毁工作线程的开销很大;
2、活动的线程也消耗系统资源。每个线程本身都会占用一定的内存(每个线程需要大约1MB内存),这样就很容易导致系统的内存不足;
3、Java虚拟机会为每个线程分配独立的堆栈空间,工作线程数目越多,系统开销越大,而且增加了Java虚拟机调度线程的负担,增加了线程之间同步的复杂性,提高了线程死锁的可能性。
4、工作线程的许多时间都浪费在阻塞I/O操作上,Java虚拟机需要频繁地转让CPU的使用权,使进入阻塞状态的线程放弃CPU,再把CPU分配给处于可运行状态的线程。
相关推荐
java socket tcpip多线程网络通信服务器客户端
基于多线程实现的JavaSocket客户端-服务端点对点异步通信程序代码
网络通信之Java Socket多线程通信.pdf
JAVA写的多线程socket通信程序源码.我写的作业。
java tcp socket 多线程多句通信
主要介绍了Java Socket实现多线程通信功能,结合具体实例形式较为详细的分析了java多线程通信的原理及客户端、服务器端相应实现技巧,需要的朋友可以参考下
java多线程并发控制通信,用hibernate存储信息,数据库mysql.
Java Socket 传输自定义对象,服务端可以接受多个客户端的连接。
NULL 博文链接:https://yangliuwillow.iteye.com/blog/1544038
java Socket 和多线程 实现的通信客户端和服务端 可并发连接
2. 实现socket多线程,监听端口1314,最大socket队列100,都可以人为设置 3. 模拟了对串口助手发送来的一串十六进制数据进行解析 4. 使用串口助手发送数据,模拟数据如图“模拟数据.png”所示 爱吃凉拌辣芒果 ...
Java编写的简易socket通信,既有单线程socket通信也有多线程socket通信,使用Java原生sdk实现,可以运行。
NULL 博文链接:https://1358440610-qq-com.iteye.com/blog/2115715
使用了多线程创建了双工的通信,控制台输入输出文字。在同一网段内先启动client,然后是server(说反了)java -jar执行可执行jar
本程序利用了Java多线程进行了TCP的端口扫描,能够满足一般的业务需求,适用与网管或网络安全从事者
实现Java Socket聊天多线程编程,图形化界面,多人聊天(群聊),私人聊天,是基于本地模拟的Java聊天程序。 Java Socket聊天程序是我用了三天的时间写出来,用Netbeans建的工程,图形化界面是Netbeans拖拉出来的,...
socket的客户端与服务端,通过开多线程与通信
基于java socket网络编程实现的五子棋游戏,可多人在线玩耍,聊天
socket通信的demo,采用了多线程收发,别的如题
1)设计程序,分别构建通信的两端:服务器端和客户端应用程序,套接字类型为面向连接的Socket,自己构建双方的应答模式,实现双方的... 6,注意理解程序的线程、Socket的基本动作(Accept、Connect、Send、Receive)等;