首页 文章

.NET Socket.Receive()没有从Java SocketServer接收大数据流

提问于
浏览
4

Java套接字服务器


我有一个Java进程,使用java.io.ServerSocket在TCP套接字上创建一个监听器,如下所示(简化):

ServerSocket server = new ServerSocket(4444,20);
server.accept();

收到请求时,Java进程会触发一个工作线程,然后工作者使用java.io.PrintWriter和java.net.Socket发送一个JSON字符串:

PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
out.println("JSON STRING");
out.flush();
out.close();
clientSocket.close();

我简化了Java代码,但这基本上就是它所做的一切 .


.NET套接字客户端


接下来,我有一个.NET应用程序,它与托管此Java进程的计算机进行通信:

//Create Connection
Socket clientSocket = new Socket(AddressFamily.InterNetwork, 
                                 StreamType.Stream, ProtocolType.Tcp);
mySocket.Connect("192.168.1.102", 4444);

//Initialize Byte Buffer Larger than Expected JSON String and Read Bytes
byte[] receivedData = new byte[524288];
int numberOfBytes = clientSocket.Receive(receivedData, SocketFlags.None);
clientSocket.Close();

//Populate a new byte array of the exact size received with the received data
byte[] formatedBytes = new byte[numberOfBytes];
for (int i=0; i< numberOfBytes; i++)
{
    formatedBytes[i] = receivedData[i];
}

//Convert Byte Array to String & Output Results
Response.ClearContent();
Response.ContentType("text/plain");
Response.Write(new System.Text.ASCIIEncoding().GetString(receivedData));

我的问题是,无论出于何种原因,当我尝试在Socket Stream上发送稍大的JSON字符串时,此实现不起作用 . 对于小数据量(小于2KB),我已成功测试了此实现,超过100个客户端连接和接收数据没有任何问题,但是尝试将JSON字符串大小增加到大约256KB会导致.NET应用程序截断结果 . 增加字节缓冲区数组的大小也无济于事 - 似乎.NET应用程序在传输所有数据之前丢弃了连接,或者Java应用程序没有使用PrintWriter发送整个String .

我们将非常感谢您对这个问题的任何见解 - 如果我自己取得任何进展,我会发布任何更新 .


这是我来的解决方案 - 服务器现在工作得很好!再次感谢!


byte[] receivedData = new byte[512000]; // 4 Meg Buffer

    Socket mySocket = new Socket(AddressFamily.InterNetwork, 
                               SocketType.Stream, ProtocolType.Tcp);
    mySocket.Connect("172.26.190.205", 4444);
    mySocket.ReceiveBufferSize = 8192;

    int numberOfBytesRead = 0;
    int totalNumberOfBytes = 0;
    do
    {
        numberOfBytesRead = mySocket.Receive(receivedData,totalNumberOfBytes ,
                            mySocket.ReceiveBufferSize,SocketFlags.None);
        totalNumberOfBytes += numberOfBytesRead;
    } 
    while (numberOfBytesRead > 0);
    mySocket.Close();

    byte[] formatedBytes = new byte[totalNumberOfBytes ];
    for (int i = 0; i < totalNumberOfBytes ; i++)
    {
        formatedBytes[i] = receivedData[i];
    }
    Response.ClearContent();
    Response.ContentType = "text/plain";
    Response.Write(new System.Text.ASCIIEncoding().GetString(formatedBytes));

2 回答

  • 3

    虽然TCP是概念中的流,但底层IP发送和接收数据包 . 对于应用程序,这意味着您始终从套接字 in a loop 读取,因为发送方的单个"write"可能会导致接收方多个"reads",反之亦然 .

    这归结为这样一个事实,即TCP / IP堆栈实现如何将您发送的数据拆分为数据包 . 接收方,也就是网络堆栈,不知道预期有多少字节 . 它只需要它获取的内容并唤醒等待该套接字的进程(如果有的话),否则缓冲字节 .

    你的情况很简单 - 只需继续读取套接字,直到看到 EOF ,即读取零字节 . 但一般而言,您需要一个应用程序级协议,该协议可定义消息长度,为消息边界 Build 规则,或将显式长度信息嵌入到消息本身中 .

  • 0

    //初始化字节缓冲区大于预期的JSON字符串和读取字节byte [] receivedData = new byte [524288]; int numberOfBytes = clientSocket.Receive(receivedData,SocketFlags.None); clientSocket.Close();

    好的,它读取到达缓冲区的所有字节 . 然后关闭了流 . UPS .

    阅读文档 - 了解Receive方法 . 你必须反复调用它,直到你得到更多的数据 . 它会阻塞,直到有些数据到达,然后返回 . 它不会等到所有数据都到达 .

相关问题