我想问为什么服务器只显示其中一个客户端第一次发送数据,我的意图是有两个客户端而只是想发送一些整数,服务器读取它然后再将它发送回其他客户端,然后等待此客户端发送信息并将其发送到其他客户端(切换它们)。但只有第一次发送数据,它是在服务器上读取?
服务器:
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();
}
}
答案 0 :(得分:1)
看起来你正在从客户端1读取2个整数(猜测它是一个错字)所以
尝试更改
out2.writeInt(in1.readInt());
到
out2.writeInt(inint1);
另外,正如@JohnBollinger所说,
单独的数据*流已创建,但两个集都连接到套接字s1,而不是每个套接字都设置一个。
DataInputStream in1=new DataInputStream(s1.getInputStream());
DataOutputStream out1=new DataOutputStream(s1.getOutputStream());
DataInputStream in2=new DataInputStream(s1.getInputStream());
DataOutputStream out2=new DataOutputStream(s1.getOutputStream());
此处的所有流都引用同一个客户端。
答案 1 :(得分:0)
您正在使用阻塞套接字。出于这个原因,当你打电话给任何类型的&#34;阅读&#34;方法,它将阻塞,直到从客户端收到数据。
所以,一个线程是不够的。第一次读取将被阻止,第二次读取将永远不会执行,除非第一个客户端实际发送了一些内容。
解决方案1:每个插槽连接使用一个线程(建议,因为更容易)。 解决方案2:使用非阻塞套接字(不建议使用,但对于某些性能关键方案很困难但很好)。
答案 2 :(得分:0)
看这里:
int inint1=in1.readInt();
System.out.println("Recived from 1 " + inint1);
System.out.println("Sending to 2 ");
out2.writeInt(in1.readInt());
首先,您从第一个客户端读取int
。然后你打印一些东西并从同一个客户端读取第二个int
。但是客户端等待来自服务器的int
,因此不会发送秒,因此服务器会阻塞。
用out2.writeInt(inint1);
替换上面代码的最后一行,看看它是否有效。我还没有阅读所有代码,所以我不确定是否还有其他错误。