serversocket启动时并非从主线程开始接受所有连接
我发现从非主线程启动时,ServerSocket 变得部分不负责任。为什么?当我在主线程中启动 ServerSocket 时,一切正常。
主启动类:
public class gui
{
public static void main(String args[])
{
new CpServer();
}
}
启动ServerSocket
并接受连接的线程类:
public class CpServer extends Thread {
private ServerSocket server = null;
public CpServer()
{
try {
server =new ServerSocket(3700,1,InetAddress.getByName("0.0.0.0") );
} catch (Exception ex) {
System.out.println( "exception on start socket"+ ex.getMessage());
}
start();
}
public void run()
{
while(true)
{
try {
new NBSrvThr(server.accept()).start();
System.out.println("Accept");
} catch (Exception e)
{
System.out.println("Error acception connection "+e.getMessage());
}
}
}
}
通信线程:
public class NBSrvThr extends Thread {
private Socket socket = null;
public NBSrvThr(Socket socket) {
this.socket = socket;
}
public void run() {
try (
BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream()));
) {
String inputLine;
while ((inputLine = in.readLine()) != null)
{
System.out.println("got packet: "+inputLine);
break;
}
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端测试应用
启动10个连接的主启动类:
public class NBClientManyRuns {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println("Creating thread "+Integer.toString(i));
try {
NBThr.proceed(Integer.toString(i));
} catch (Exception e) {
System.out.println("Eception itn thr create "+Integer.toString(i));
}
}
}
}
Cleint连接线程:
public class NBThr extends Thread {
public String id;
public static void proceed(String ID)
{
NBThr t= new NBThr() ;
t.id = ID;
t.start();
}
public void run()
{
System.out.println("Starting thread"+ " id="+ id);
String hostName = "127.0.0.1";
int portNumber = 3700;
try (
Socket socket = new Socket(hostName, portNumber);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
)
{
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
socket.getOutputStream().write("hello".getBytes());
System.out.println("Send done " + hostName + " id="+ id);
} catch (Exception e) {
System.out.println("Exception " + e.getMessage() +" "+ hostName + " id="+ id);
}
System.out.println("Leaving thread"+ " id="+ id);
}
}
控制台输出:
客户端测试结果显示并非所有连接都被接受:
Creating thread 0
Creating thread 1
Creating thread 2
Creating thread 3
Starting thread id=0
Starting thread id=2
Starting thread id=1
Creating thread 4
Starting thread id=3
Creating thread 5
Starting thread id=4
Creating thread 6
Starting thread id=5
Creating thread 7
Starting thread id=6
Creating thread 8
Creating thread 9
Starting thread id=7
Starting thread id=8
Starting thread id=9
Send done 127.0.0.1 id=2
Send done 127.0.0.1 id=6
Leaving thread id=2
Leaving thread id=6
Send done 127.0.0.1 id=7
Leaving thread id=7
Send done 127.0.0.1 id=4
Leaving thread id=4
Exception Connection refused: connect 127.0.0.1 id=9
Leaving thread id=9
Exception Connection refused: connect 127.0.0.1 id=1
Leaving thread id=1
Exception Connection refused: connect 127.0.0.1 id=8
Exception Connection refused: connect 127.0.0.1 id=5
Exception Connection refused: connect 127.0.0.1 id=0
Leaving thread id=0
Leaving thread id=8
Exception Connection refused: connect 127.0.0.1 id=3
Leaving thread id=3
Leaving thread id=5
服务器控制台仅显示4个接受的连接:
Accept
Accept
Accept
Accept
got packet: hello
got packet: hello
got packet: hello
got packet: hello
I found that ServerSocket
becomes partly irresponsible when when started from not main thread. Why? When I start ServerSocket in main thread everything works fine.
Main start class:
public class gui
{
public static void main(String args[])
{
new CpServer();
}
}
Thread class that starts ServerSocket
and accepts connections:
public class CpServer extends Thread {
private ServerSocket server = null;
public CpServer()
{
try {
server =new ServerSocket(3700,1,InetAddress.getByName("0.0.0.0") );
} catch (Exception ex) {
System.out.println( "exception on start socket"+ ex.getMessage());
}
start();
}
public void run()
{
while(true)
{
try {
new NBSrvThr(server.accept()).start();
System.out.println("Accept");
} catch (Exception e)
{
System.out.println("Error acception connection "+e.getMessage());
}
}
}
}
Communication thread:
public class NBSrvThr extends Thread {
private Socket socket = null;
public NBSrvThr(Socket socket) {
this.socket = socket;
}
public void run() {
try (
BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream()));
) {
String inputLine;
while ((inputLine = in.readLine()) != null)
{
System.out.println("got packet: "+inputLine);
break;
}
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client test application
Main start class that starts 10 connections:
public class NBClientManyRuns {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println("Creating thread "+Integer.toString(i));
try {
NBThr.proceed(Integer.toString(i));
} catch (Exception e) {
System.out.println("Eception itn thr create "+Integer.toString(i));
}
}
}
}
Cleint connection thread:
public class NBThr extends Thread {
public String id;
public static void proceed(String ID)
{
NBThr t= new NBThr() ;
t.id = ID;
t.start();
}
public void run()
{
System.out.println("Starting thread"+ " id="+ id);
String hostName = "127.0.0.1";
int portNumber = 3700;
try (
Socket socket = new Socket(hostName, portNumber);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
)
{
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
socket.getOutputStream().write("hello".getBytes());
System.out.println("Send done " + hostName + " id="+ id);
} catch (Exception e) {
System.out.println("Exception " + e.getMessage() +" "+ hostName + " id="+ id);
}
System.out.println("Leaving thread"+ " id="+ id);
}
}
Console output:
Client test result shows that not all connections was accepted:
Creating thread 0
Creating thread 1
Creating thread 2
Creating thread 3
Starting thread id=0
Starting thread id=2
Starting thread id=1
Creating thread 4
Starting thread id=3
Creating thread 5
Starting thread id=4
Creating thread 6
Starting thread id=5
Creating thread 7
Starting thread id=6
Creating thread 8
Creating thread 9
Starting thread id=7
Starting thread id=8
Starting thread id=9
Send done 127.0.0.1 id=2
Send done 127.0.0.1 id=6
Leaving thread id=2
Leaving thread id=6
Send done 127.0.0.1 id=7
Leaving thread id=7
Send done 127.0.0.1 id=4
Leaving thread id=4
Exception Connection refused: connect 127.0.0.1 id=9
Leaving thread id=9
Exception Connection refused: connect 127.0.0.1 id=1
Leaving thread id=1
Exception Connection refused: connect 127.0.0.1 id=8
Exception Connection refused: connect 127.0.0.1 id=5
Exception Connection refused: connect 127.0.0.1 id=0
Leaving thread id=0
Leaving thread id=8
Exception Connection refused: connect 127.0.0.1 id=3
Leaving thread id=3
Leaving thread id=5
Server console shows only 4 accepted connections:
Accept
Accept
Accept
Accept
got packet: hello
got packet: hello
got packet: hello
got packet: hello
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为线程导致饥饿的线程存在一些问题。我建议将线程池用于此目的
I think there is some problem with the threads where the threads are leading to starvation.i would suggest using thread pools for this purpose