有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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();
    }
}

共 (3) 个答案

  1. # 1 楼答案

    看这里:

    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);,看看它是否有效。我还没有读完所有的代码,所以我不确定是否还有其他错误

  2. # 2 楼答案

    看起来你正在从客户端1读取2个整数(猜是打字错误),所以

    试着改变

    out2.writeInt(in1.readInt());
    

    out2.writeInt(inint1);
    

    此外,正如@JohnBollinger所提到的

    Separate Data*Streams are created, but both sets are connected to socket s1, instead of one set to each socket.

        DataInputStream in1=new DataInputStream(s1.getInputStream());
        DataOutputStream out1=new DataOutputStream(s1.getOutputStream());
    
        DataInputStream in2=new DataInputStream(s1.getInputStream());
        DataOutputStream out2=new DataOutputStream(s1.getOutputStream());
    

    这里的所有流都引用同一个客户端

  3. # 3 楼答案

    您正在使用阻塞套接字。因此,当您调用任何类型的“read”方法时,它都会阻塞,直到从客户端接收到数据

    所以,一根线是不够的。第一次读取将被阻止,第二次读取将永远不会执行,除非第一个客户机实际发送了一些内容

    解决方案1:每个套接字连接使用一个线程(推荐,因为更容易)。 解决方案2:使用非阻塞套接字(不建议使用,难度较大,但适用于某些性能关键的场景)