在readLine()之后使用readLong()进行套接字通信

时间:2012-08-20 08:21:09

标签: java sockets serversocket

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

SERVER

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

2 个答案:

答案 0 :(得分:3)

你的问题是BufferedReader是来自套接字输入流的缓冲字节,所以长{9}的值不在DataInputStream中,因为BufferedReader读取了它并且正在缓冲它。通常,您不希望在同一个底层流中使用2个不同的包装器,尤其是在缓冲的情况下。与您的Server课程相同,但这似乎至少有效。

您的客户端只需要为套接字的输入流使用一个包装器。您应该坚持使用DataInputStream以及服务器代码,在服务器上使用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);
}

答案 1 :(得分: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()));
}

}
相关问题