开发者

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

开发者 https://www.devze.com 2023-01-23 00:45 出处:网络
Java Socket Server I have a Java process that is creating a listener on a TCP Socket using java.io.ServerSocket something like this (simplified):

Java Socket Server


I have a Java process that is creating a listener on a TCP Socket using java.io.ServerSocket something like this (simplified):

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:

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.


.NET Socket Client


Next I have a .NET Application that communicates with the machine hosting this Java Process:

//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, t开发者_StackOverflow社区his implementation does not work when I attempt to send slightly larger JSON Strings over the Socket Stream. 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. 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.

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. 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. 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, i.e. zero bytes read. 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]; int numberOfBytes = clientSocket.Receive(receivedData, SocketFlags.None); clientSocket.Close();

Ok, that reads all the bytes that arrive in the buffer. THen closes the stream. Ups.

Read the documentation - for the Receive method. 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号