How to finish writing data without closing NetworkStream in C #

I have a client application that serializes an object and sends it to the server application. The server must deserialize the object, make changes to it, then serialize it and send it back.

Server Code:

TcpClient client = server.AcceptTcpClient(); using(NetworkStream stream = client.GetStream()) { using(StreamReader streamReader = new StreamReader(stream)) { string xmlData = streamReader.ReadToEnd(); } } 

ReadToEnd is not returned if the client does not close the stream. But if the client closes the stream, I cannot send a response.

Is there a better way to do this?

+6
source share
2 answers

You can signal “end of data” by closing only your half of a duplex TCP connection . This is done using Socket.Disconnect .

See how this works with this example that I saved, similar to yours. The client sends the data, and then calls Disconnect ; this allows ReadToEnd return, while maintaining half the server’s opening. Then the server sends a response, and also disconnects, after which both parties can Close to close their connection to tear it off.

 static void Main(string[] args) { Action clientCode = () => { var buffer = new byte[100]; var clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); clientSocket.Connect(IPAddress.Loopback, 6690); clientSocket.Send(buffer); clientSocket.Disconnect(false); Console.WriteLine("Client: message sent and socket disconnected."); while (true) { var bytesRead = clientSocket.Receive(buffer); if (bytesRead == 0) { break; } Console.WriteLine("Client: read " + bytesRead + " bytes."); } clientSocket.Dispose(); }; var server = new TcpListener(IPAddress.Loopback, 6690); var thread = new Thread(new ThreadStart(clientCode)); server.Start(); thread.Start(); var client = server.AcceptTcpClient(); using(NetworkStream stream = client.GetStream()) { using(StreamReader streamReader = new StreamReader(stream)) { var data = streamReader.ReadToEnd(); Console.WriteLine("Server: read " + data.Length + " bytes."); // Since we 're here we know that the client has disconnected. // Send the response before StreamReader is disposed, because // that will cause the socket itself to be closed as well! Thread.Sleep(TimeSpan.FromSeconds(1)); Console.WriteLine("Server: sending response."); stream.Write(new byte[10], 0, 10); Console.WriteLine("Server: closing socket."); } } server.Stop(); Console.WriteLine("Server: waiting for client thread to complete."); thread.Join(); return; } 
+10
source

You can use a higher level platform, such as WCF, or if you are configured to manage your own streams, then do not use ReadToEnd () - use ReadLine () and send messages to clients as strings) or use Read () and have special character ( sentinel ) represent the end of a message.

+3
source

Source: https://habr.com/ru/post/897944/


All Articles