首次获取数据后,服务器套接字阻塞

时间:2015-12-08 21:24:32

标签: java sockets

我想问为什么服务器只显示其中一个客户端第一次发送数据,我的意图是有两个客户端而只是想发送一些整数,服务器读取它然后再将它发送回其他客户端,然后等待此客户端发送信息并将其发送到其他客户端(切换它们)。但只有第一次发送数据,它是在服务器上读取?

服务器:

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 个答案:

答案 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);替换上面代码的最后一行,看看它是否有效。我还没有阅读所有代码,所以我不确定是否还有其他错误。