public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 8777);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
DataInputStream in = new DataInputStream(socket.getInputStream());

// write
out.write("Save the cheer leader, save the world.".getBytes());
out.flush();
//socket.shutdownOutput(); //如果没有这句则无法写数据给服务端,客户端会在read那里一直等着

// read
int read = 0;
byte[] buff = new byte[1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while (true) {
read = in.read(buff); // 如没有上面的shutdownOutput(),客户端就一直在这里等着
if (read == -1)
break;
bos.write(buff, 0, read);
}
bos.flush();
System.out.println("Reply: " + new String(bos.toByteArray()));

bos.close();
in.close();
out.close();
}
这是tcp的客户端,为什么不能发送数据给服务端?就一直在等着

解决方案 »

  1.   


    public static void main(String[] args) throws Exception {
    Socket socket = new Socket("127.0.0.1", 8777);
    DataOutputStream out = new DataOutputStream(socket.getOutputStream());
    DataInputStream in = new DataInputStream(socket.getInputStream());// write
    out.write("Save the cheer leader, save the world.".getBytes());
    out.flush();
    //socket.shutdownOutput(); //如果没有这句则无法写数据给服务端,客户端会在read那里一直等着// read
    int read = 0;
    byte[] buff = new byte[1024];
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    while (true) {
    read = in.read(buff); // 如没有上面的shutdownOutput(),客户端就一直在这里等着
    if (read == -1)
    break;
    bos.write(buff, 0, read);
    }
    bos.flush();
    System.out.println("Reply: " + new String(bos.toByteArray()));bos.close();
    in.close();
    out.close();
    } 这是源码
      

  2.   


    答:恰恰相反,问题出在服务器的代码上,客户机将代码发给服务器后,服务器收到后,由于服务器没法知道客户机数据已发完,会一直在等待客户机继续发数据,这样客户机的read(...)就读不到服务器发的数据(因为服务器根本没有发),因而:客户机就一直在这里等着了
      

  3.   

    答:客户机先发数据长度,然后再发字节数据即要.
    如:客户机:
    // write
    String s="Save the cheer leader, save the world.";
    out.writeInt(s.getBytes().length);
    out.write(s.getBytes());
    out.flush();而:服务器:
    //readint len=din.readInt();
    然后再读len个字节,读完后,立即向客户机发响应.
      

  4.   

    问:这样的确好使,但是如果一开始发不是包的长度,如何读完数据呢?请问还有其他的方法吗?
    答:当然有啊.由于你没有规定:客户机方发送字节数据时,何时已发送完(这个标记或数据长度),这样服务器方就没有办法判客户机方已发送完数据.这时完全可以采用FTP的数据传送方式.即:每当客户机方要向服务器发送数据时,向服务器的专门的接收数据端口发起连接.发送完成,客户机方这个数据连接调用close()关闭.此时:服务器方读到-1,就表示数据已接受完成.
    一句话:都是通过各种方法,知之服务器方,字节数据已发送完. 因为:服务器方,只有接收完数据后,对该数据处理好后,视情况再返回数据给客户方的.   这是通信协议的时序. 要协调好.
      

  5.   

    谢谢。这分是给你的了。。刚才试了下,发现用读长度的方法不好使了。。是这样的
    客户端send -> 服务端receive -> 服务端send -> 客户端receive -> 客户端send -> 服务端receive -> ...
    结果这样还是会卡住。。这有点像长连接吧?但是我只需要做几次数据交换而不断开socket.
    两边都是用一样的代码读写。代码如下:
    reader 是读数据流
    writer 是写数据流 private byte[] read() throws IOException {
    int length = reader.readInt();
    if (length == -1)
    return null;
    byte[] bytes = new byte[length];
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    out.write(ConvertUtil.intToBytes(length));
    int read = 0;
    while ( (read = reader.read(bytes, read, bytes.length - read)) > 0 ) {
    out.write(bytes, 0, read);
    }
    out.flush();
    return out.toByteArray();
    }

    private void write(byte[] bytes) throws IOException {
    if (bytes == null)
    return;
    writer.write(bytes);
    writer.flush();
    }
      

  6.   

    sorry,原来是客户端那边写错了。可行了。结贴