简体   繁体   English

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

[英].NET Socket.Receive() Not Receiving Large Data Streams from Java SocketServer


Java Socket Server Java套接字服务器


I have a Java process that is creating a listener on a TCP Socket using java.io.ServerSocket something like this (simplified): 我有一个Java进程,使用java.io.ServerSocket在TCP套接字上创建一个监听器,如下所示(简化):

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

The Java Process Fires off a Worker Thread when a Request Is Received and the Worker then sends a JSON string using java.io.PrintWriter and java.net.Socket: 收到请求时,Java进程会触发一个工作线程,然后工作者使用java.io.PrintWriter和java.net.Socket发送一个JSON字符串:

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

I have simplified the Java code but this is essentially all it is doing. 我简化了Java代码,但这基本上就是它所做的一切。


.NET Socket Client .NET套接字客户端


Next I have a .NET Application that communicates with the machine hosting this Java Process: 接下来,我有一个.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));

My Issue is that for whatever reason, this implementation does not work when I attempt to send slightly larger JSON Strings over the Socket Stream. 我的问题是,无论出于何种原因,当我尝试在Socket Stream上发送稍大的JSON字符串时,此实现不起作用。 With small datasizes (under 2KB) I have successfully tested this implementation with over 100 Clients connecting and receiving data without any issues, however trying to increase the JSON String size to about 256KB results in the .NET Application truncating the results. 对于小数据量(小于2KB),我已成功测试了此实现,超过100个客户端连接和接收数据没有任何问题,但是尝试将JSON字符串大小增加到大约256KB会导致.NET应用程序截断结果。 Increasing the size of the byte buffer array does not help either - it seems as if the .NET application is dropping the connection before all the data is transmitted, or the Java Application is not sending the entire String using the PrintWriter. 增加字节缓冲区数组的大小也无济于事 - 似乎.NET应用程序在传输所有数据之前丢弃了连接,或者Java应用程序没有使用PrintWriter发送整个String。

Any insight into this issue would be greatly appreciated - I'll post any updates if I make any progress myself. 我们将非常感谢您对这个问题的任何见解 - 如果我自己取得任何进展,我会发布任何更新。


Here is the Solution I came to - Server Is Working Great Now! 这是我来的解决方案 - 服务器现在工作得很好! Thanks Again! 再次感谢!


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

While TCP is a stream in concept, the underlying IP sends and receives packets . 虽然TCP是概念中的 ,但底层IP发送和接收数据包 For the application this means that you always read from socket in a loop , because single "write" by the sender might result in multiple "reads" by the receiver, and the other way around. 对于应用程序,这意味着您始终 在循环中读取套接字,因为发送方的单个“写入”可能会导致接收方多次“读取”,反之亦然。

This boils down to the fact that it's up to the TCP/IP stack implementation how to split the data you send into packets. 这归结为这样一个事实,即TCP / IP堆栈实现如何将您发送的数据拆分为数据包。 The receiving side, again the network stack, does not know how many bytes to expect. 接收方,也就是网络堆栈,不知道预期有多少字节。 It just takes what it got and wakes up the process that waits on that socket, if there's one, or buffers the bytes otherwise. 它只需要它获取的内容并唤醒等待该套接字的进程(如果有的话),否则缓冲字节。

Your case is easy - just keep reading from the socket until you see the EOF , ie zero bytes read. 你的情况很简单 - 只需继续读取插座,直到你看到EOF ,即读取零字节。 But in general you need an application-level protocol that either defines message lengths, establishes rules for message boundaries, or embeds explicit length information into messages themselves. 但一般而言,您需要一个应用程序级协议,该协议可定义消息长度,为消息边界建立规则,或将显式长度信息嵌入到消息本身中。

//Initialize Byte Buffer Larger than Expected JSON String and Read Bytes byte[] receivedData = new byte[524288]; //初始化字节缓冲区大于预期的JSON字符串和读取字节byte [] receivedData = new byte [524288]; int numberOfBytes = clientSocket.Receive(receivedData, SocketFlags.None); int numberOfBytes = clientSocket.Receive(receivedData,SocketFlags.None); clientSocket.Close(); clientSocket.Close();

Ok, that reads all the bytes that arrive in the buffer. 好的,它读取到达缓冲区的所有字节。 THen closes the stream. 然后关闭了流。 Ups. UPS。

Read the documentation - for the Receive method. 阅读文档 - 了解Receive方法。 YOu have to repeatedly call it until you get no more data. 你必须反复调用它,直到你得到更多的数据。 It will block until SOME data arrives, then return this. 它会阻塞,直到有些数据到达,然后返回。 It will NOT wait until ALL data has arrived. 它不会等到所有数据都到达。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM