对了,请问大家在TCP套接字中(SendQ)发送队列 与 (RecvQ)接收队列 大小是多少啊?

解决方案 »

  1.   


    private static void sendBytes(Socket socket, InputStream fileIn)
                throws IOException
        {
            OutputStream sockOut = socket.getOutputStream();
            int bytesRead = 0;
            byte[] buffer = new byte[BUFSIZE];
            while ((bytesRead = fileIn.read(buffer)) != -1)//这里会阻塞的,因为如果没有字节读,则阻塞
            {
                sockOut.write(buffer, 0, bytesRead);
                System.out.print("W");
            }
            System.out.println("\nClient send data complete!");
            socket.shutdownOutput();
            System.out.println("Client is deadlock? No");
        }
    这段代码有问题,
      

  2.   

    读socket 中 read(buffer) != -1 只在一种情况成立,就是在对方调用了 socket.shutdownOutput();方法.
    其它情况 永远不会有 -1出现, 所以你这里永远不可能结束,除非两种情况:
    1 对方调用了 socket.shutdownOutput();//你会收到-1, 但是如果对方程序不是你写的,不能保证哦.
    2 对方调用了 socket.close(); //会有异常,则结束,但是异常必须你再次读写数据时才会出现!!
      

  3.   


    //不管是客户机,还是服务器程序,你这段代码只能是学习用, 要用到项目中去, 不能这么简单的写.
    while ((bytesRead = in.read(buffer)) != -1)
                {
                 out.write(buffer, 0, bytesRead);
    }用如下代码, 自己再完善:try{ int pava=0;
    int cava=0;
    int sumb=0;
    int i=0;
    int c=0;
    ByteArrayOutputStream buffeOut =new ByteArrayOutputStream();
    byte readbuf[] = new byte[10240];
    while (socket.isConnected() && !socket.isClosed()) {
    i++;
    pava =in.available();
    if(pava>0){
    while ((c = in.read(readbuf)) != -1) {
    buffeOut.write(readbuf, 0, c);
    sumb =sumb + c;
    cava =in.available();
    if(cava<=0){
    Thread.sleep(100);
    cava =in.available();
    if(cava<=0) break;
    }
    }
    String strin = new String(buffeOut.toByteArray(),"utf-8");
    System.out.println("读取流数据内容: "+strin+","+sumb);
    buffeOut.reset();
    //读完后回复信息.
    out.write((i+",我是服务器,已收到数据!").getBytes("utf-8"));
    out.flush();
    if(c == -1) break;//对方关闭了输入流.
    }else{
    sumb=0;
    out.write((i+",我是服务器,请发送数据!").getBytes("utf-8"));
    out.flush();
    Thread.sleep(1000);
    }
    }
    } catch (SocketException e) {
    e.printStackTrace();
    } catch (InterruptedException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    System.out.println("Request,NO["+requestCount+"],读取流数据完成.");
    }
      

  4.   


    谢谢你,我的问题自己解决了,首先你将的不错,但是有一点你分析错了,当调用sockOut.write(buffer, 0, bytesRead)时,我发现程序是到这里才被阻塞,这说明——"接收端SendQ队列已被填满,所以才会造成服务端调用sockOut.write(buffer, 0, bytesRead)时阻塞", 这个问题与 "Socket的接收队列SendQ"有关!不过,这里还是要谢谢你,while ((bytesRead = in.read(buffer)) != -1) 这种写法得看用在什么场景下,也可以使用“自定义消息边界符”来实现。谢谢大家!
      

  5.   


    “socket 中 read(buffer) != -1 只在一种情况成立” ,你说的这个观点是错的,正确观点是:只有两种观点成立,1.socket.shutdownOutput() 2.socket.close() ,建议你自己试试!
      

  6.   

    我这里写的代码,只是学习使用,不建议大家直接用到项目中,仅仅是学习使用哦!
    正确的代码如下:/*
     * 服务端
     */
    public class TestServer
    {
        public static void main(String[] args) throws IOException
        {
            System.out.println("服务端启动......");
            ServerSocket server = new ServerSocket(8888);        Socket client = server.accept();
            OutputStream output = client.getOutputStream();
            InputStream input = client.getInputStream();        byte[] temp = new byte[10];
            int realLen = 0;
            while ((realLen = input.read(temp)) != -1)
            {
                System.out.println("【服务端】正在发送数据......");
                output.write(temp, 0, realLen);
            }
            System.out.println("【客户端】发送数据完毕!");
            output.flush();        client.close();
        }
    }
    /*
     * 客户端
     */
    public class TestClient
    {
        public static void main(String[] args) throws UnknownHostException,
                IOException
        {
            System.out.println("客户端启动......");
            final Socket client = new Socket(InetAddress.getLocalHost(), 8888);        final OutputStream out = client.getOutputStream();
            InputStream in = client.getInputStream();
            final FileInputStream fileIn = new FileInputStream(new File(
                    "D:\\杂乱\\桌面.jpg"));        // 使用一个子线程发送数据
            Thread handlerExecute = new Thread()
            {
                @Override
                public void run()
                {
                    try
                    {
                        byte[] fileTemp = new byte[1024];
                        int realFileLen = 0;                    while ((realFileLen = fileIn.read(fileTemp)) != -1)
                        {
                            System.out.println("【客户端】正在发送数据......");
                            out.write(fileTemp, 0, realFileLen);
                        }
                        System.out.println("【客户端】发送数据完毕!");                    out.flush();
                        client.shutdownOutput();
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            };        handlerExecute.start();        // 使用主线程接收数据
            ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
            int realLen = 0;
            byte[] temp = new byte[10];
            while ((realLen = in.read(temp)) != -1)
            {
                byteArray.write(temp, 0, realLen);
            }
            byte[] recvByte = byteArray.toByteArray();        System.out.println("客户端接收消息成功,消息长度:" + recvByte.length);    }
    }一切有完好如初!再次感谢 guishuanglin !!!