2

为什么这个程序不能正常工作?客户端读取 SOME_MESSAGE 之后没有任何反应。似乎来自服务器的 println 方法在某种程度上对传输长类型数字有影响。

服务器

import java.net.*;
import java.io.*;

public class Server {

  public static void main(String[] args) throws Exception {
    ServerSocket socket = new ServerSocket(9999);
    while (true) {
      Socket sock = socket.accept();
      PrintWriter out = new PrintWriter(new BufferedWriter(
          new OutputStreamWriter(sock.getOutputStream())), true);
      DataOutputStream outByte = new DataOutputStream(sock.getOutputStream());
      out.println("SOME_MESSAGE");
      outByte.writeLong(948L);
    }
  }
}

客户

import java.net.*;
import java.io.*;

public class Client {

  public static void main(String[] args) throws Exception {
    Socket sock = new Socket("127.0.0.1", 9999);
    DataInputStream inByte = new DataInputStream(sock.getInputStream());
    BufferedReader in = new BufferedReader(new InputStreamReader(
        sock.getInputStream()));

    System.out.println(in.readLine());
    long number = inByte.readLong();
    System.out.println(number);
  }
}
4

2 回答 2

3

您的问题是BufferedReader正在缓冲来自套接字输入流的字节,因此长 948 值不在其中,DataInputStream因为BufferedReader它已读取并正在缓冲它。通常,您不希望在同一个底层流周围使用 2 个不同的包装器,尤其是在一个被缓冲的情况下。与您的Server班级相同,但这似乎至少有效。

您的客户端只需要对套接字的输入流使用一个包装器。您应该坚持使用DataInputStreamand 与服务器代码一起使用DataInputStream.readUTF(),在客户端上使用同时DataOutputStream.writeUTF()在服务器上使用,同时摆脱BufferedReaderPrintWriter.

所以在服务器上:

while(true) {
    Socket sock = socket.accept();
    DataOutputStream outByte = new DataOutputStream(sock.getOutputStream());
    outByte.writeUTF("SOME_MESSAGE");
    outByte.writeLong(948L);
    outByte.flush();

}

在客户端:

public static void main(String[]args)throws Exception
{
    Socket sock = new Socket("127.0.0.1",9999);
    DataInputStream inByte = new DataInputStream(sock.getInputStream());

    System.out.println(inByte.readUTF());
    long number  = inByte.readLong();
    System.out.println(number);
}
于 2012-08-20T08:46:44.047 回答
0

有趣的是,java 不允许这样做,因为总有更好的解决方案。您可以使用序列化来完成您的工作。

创建PayLoad如下界面

import java.io.Serializable;


public interface PayLoad extends Serializable
{
String getMessage();
//Java does not allow to define byte array of long
int getLength();

byte[] getbytes();

}

然后创建一个如下所示的实现类

public class FilePayLoad implements PayLoad
{

private final String message;
private final int length;
private final byte[] bytes;

public FilePayLoad(String message, int length, byte[] bytes)
{
    this.message = message;
    this.length = length;
    this.bytes = bytes;

}

@Override
public String getMessage()
{
    return this.message;
}

@Override
public int getLength()
{
    return this.length;
}

@Override
public byte[] getbytes()
{
    return this.bytes;
}

}

现在更改您的服务器和客户端,如下所示

服务器

public class Server
{

public static void main(String[] args) throws Exception
{
    ServerSocket socket = new ServerSocket(9999);
    while (true)
    {
        Socket sock = socket.accept();
        ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
        byte[] bytes = "SOME_MESSAGE".getBytes();
        out.writeObject(new FilePayLoad("SOME_MESSAGE", bytes.length, bytes));
        out.flush();
    }
}
}

客户

public class Client
{
public static void main(String[] args) throws Exception
{
    Socket sock = new Socket("127.0.0.1", 9999);
    ObjectInputStream inByte = new ObjectInputStream(sock.getInputStream());
    PayLoad payLoad = (PayLoad) inByte.readObject();
    System.out.println(payLoad.getMessage());
    System.out.println(payLoad.getLength());
    System.out.println(new String(payLoad.getbytes()));
}

}
于 2012-08-20T10:27:48.387 回答