java服务器socket在第一次接收到数据后阻塞
我想问为什么服务器只在第一次显示一个客户端发送数据时显示,我的意图是有两个客户端,只想发送一些整数,服务器读取数据,然后将其发送回另一个客户端,然后等待此客户端发送信息并发送给另一个客户端(切换它们)。但是只有在第一次发送数据时,才会在服务器上读取数据
服务器:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private ServerSocket serv;
private DataInputStream inFromClient1;
private DataOutputStream outToClient1;
private DataInputStream inFromClient2;
private DataOutputStream outToClient2;
public Server(){
try {
serv=new ServerSocket(8000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void listen() throws IOException{
System.out.println("Listening for connections");
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
Socket sock1;
Socket sock2;
try {
sock1 = serv.accept();
sock2=serv.accept();
handleSession(sock1,sock2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
public void handleSession(Socket s1,Socket s2) throws IOException{
DataInputStream in1=new DataInputStream(s1.getInputStream());
DataOutputStream out1=new DataOutputStream(s1.getOutputStream());
DataInputStream in2=new DataInputStream(s1.getInputStream());
DataOutputStream out2=new DataOutputStream(s1.getOutputStream());
while(true){
int inint1=in1.readInt();
System.out.println("Recived from 1 " + inint1);
System.out.println("Sending to 2 ");
out2.writeInt(in1.readInt());
int inint2=in2.readInt();
System.out.println("Recived from 2 " + inint2);
System.out.println("Sending to 1 ");
out1.writeInt(inint2);
}
}
public static void main(String[] args) throws IOException {
new Server().listen();
}
}
Client :
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Client extends JFrame implements ActionListener{
private JPanel mainPanel;
private JButton[] buttons;
private Socket socket;
private int number;
private DataInputStream fromServer;
private DataOutputStream toServer;
private boolean myTurn=true;
public Client() throws UnknownHostException, IOException{
mainPanel=new JPanel(new GridLayout(3,3));
socket=new Socket("localhost",8000);
add(mainPanel);
addbuttons();
setSize(new Dimension(500,400));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private void addbuttons(){
buttons=new JButton[9];
for(int i=1;i<10;i++){
buttons[i-1]=new JButton("Rectangle " + i);
buttons[i-1].addActionListener(this);
mainPanel.add(buttons[i-1]);
}
}
public void actionPerformed(ActionEvent arg0) {
JButton butt=(JButton) arg0.getSource();
String str=butt.getText();
String[] splitStr=str.split(" ");
number=Integer.parseInt(splitStr[1]);
System.out.println(number);
}
public void start() throws IOException{
fromServer=new DataInputStream(socket.getInputStream());
toServer=new DataOutputStream(socket.getOutputStream());
new Thread(new Runnable() {
@Override
public void run() {
Scanner in=new Scanner(System.in);
while(true){
System.out.println("Write some integer");
int inint=in.nextInt();
System.out.println("Before " + myTurn);
if(myTurn){
try {
toServer.writeInt(inint);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myTurn=false;
}
else{
int fromServint=0;
try {
fromServint=fromServer.readInt();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Recived integer " + fromServint);
buttons[fromServint].setText("Some new Text");
myTurn=true;
}
System.out.println("After " + myTurn);
}
}
}).start();
}
public static void main(String[] args) throws UnknownHostException, IOException {
new Client().start();
}
}
# 1 楼答案
看这里:
首先,从第一个客户端读取
int
。然后打印一些内容,并从同一个客户机读取第二个int
。但是客户端等待来自服务器的int
,因此不会发送第二个,因此服务器会阻塞。 将上面代码的最后一行替换为out2.writeInt(inint1);
,看看它是否有效。我还没有读完所有的代码,所以我不确定是否还有其他错误# 2 楼答案
看起来你正在从客户端1读取2个整数(猜是打字错误),所以
试着改变
到
此外,正如@JohnBollinger所提到的
这里的所有流都引用同一个客户端
# 3 楼答案
您正在使用阻塞套接字。因此,当您调用任何类型的“read”方法时,它都会阻塞,直到从客户端接收到数据
所以,一根线是不够的。第一次读取将被阻止,第二次读取将永远不会执行,除非第一个客户机实际发送了一些内容
解决方案1:每个套接字连接使用一个线程(推荐,因为更容易)。 解决方案2:使用非阻塞套接字(不建议使用,难度较大,但适用于某些性能关键的场景)