套接字读取并不总是有效

时间:2017-04-07 14:54:57

标签: java sockets

我正在构建客户端 - 服务器Java应用程序。问题是,当我用writeInt()发送Integer时,有时它会阻塞readInt()。

客户端

PrintWriter socketOut = new PrintWriter(sock.getOutputStream());
DataOutputStream d = new DataOutputStream(sock.getOutputStream());
String s = "User";
socketOut.println(s);
socketOut.flush();
d.writeInt(data[0]);
d.flush();
d.writeInt(data[1]);
d.flush();

服务器

while(true){
       System.out.println("Listening for clients...");
       clientSock = serverSock.accept();
       Scanner in = new Scanner(clientSock.getInputStream());

       String clientType = in.nextLine();

       switch(clientType){
           case "Resource":
               new Thread(new ResourceService(clientSock)).start();
               break;
           case "User":
               new Thread(new UserService(clientSock)).start();
               break;
       }

    }

用户线程

@Override
    public void run(){
        try{
        DataInputStream input = new DataInputStream(user.getInputStream());
        int i = 0;
        int a = input.readInt(); // Sometimes it blocks here.
        int b = input.readInt();
        System.out.println(a);
        System.out.println(b);
        ...

我试图根据发送到服务器的第一个字符串来区分客户端。有时服务器会读取int,有时它会阻塞。 输出的一个例子是:

Listening for clients...
Listening for clients...
Listening for clients...
Listening for clients...
Listening for clients...
1                        // here the server didn't block
100000
Listening for clients...

1 个答案:

答案 0 :(得分:2)

将DataInputStream / DataOutputStream与Scanner和PrintWriter混合使用可能不是一个好主意。建议使用Scanner和PrintWriter进行用户交互。

尝试仅使用DataOutputStream和DataInputStream。

客户端

help-button

服务器

padding-left: 0px;

用户线程

public void drSlayerQ(View view){
    Intent qIntent = new Intent(getContext(), DragonSlayerQuest.class);
    getActivity().startActivity(qIntent);
}

注1:DataInputStream / DataOutputStream使用自己的协议来写/读UTF字符串,不需要使用行终止。

注意2:PrintWriter的方法不会抛出I / O异常,你必须检查调用DataOutputStream d = new DataOutputStream(sock.getOutputStream()); String s = "User"; d.writeUTF(s); d.writeInt(data[0]); d.flush(); d.writeInt(data[1]); d.flush(); (可能不是这里的问题)。