TCP Send multiple message without closing connecti

2019-07-30 17:30发布

问题:

Hi guys i have build an app for android to get the GPS coordination and i want to send the data to my C# UWP server through TCP. As concept i have opened a socket and i want to send multiple messages without closing the socket.

socket = new java.net.Socket("192.168.2.10", 9999);
printwriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
printwriter.println("message1");
printwriter.println("message2");
printwriter.println("message3");
printwriter.println("message4");
printwriter.flush();

The problem is i only receive message1 or sometimes also messages2 on the server. The other message doesn't show on the server. I don't want to make new connection because i'm planning sending a lot of messages. If any of you know a solution would be appreciated.

I'm currently using the server code for UWP in C# from https://msdn.microsoft.com/en-us/windows/uwp/networking/sockets.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Maps
{

    class Connection
    {
        public async void Connectie()
        {
            try
            {
                System.Diagnostics.Debug.WriteLine("Waiting for connection................");

                //Create a StreamSocketListener to start listening for TCP connections.
                Windows.Networking.Sockets.StreamSocketListener socketListener = new Windows.Networking.Sockets.StreamSocketListener();

                //Hook up an event handler to call when connections are received.
                socketListener.ConnectionReceived += SocketListener_ConnectionReceived;

                //Start listening for incoming TCP connections on the specified port. You can specify any port that' s not currently in use.
                await socketListener.BindServiceNameAsync("9999");
                System.Diagnostics.Debug.WriteLine("Waiting for connection................");
            }
            catch (Exception e)
            {
                //Handle exception.
            }
        }

        private async void SocketListener_ConnectionReceived(Windows.Networking.Sockets.StreamSocketListener sender,
    Windows.Networking.Sockets.StreamSocketListenerConnectionReceivedEventArgs args)
        {
            Stream inStream = args.Socket.InputStream.AsStreamForRead();
            StreamReader reader = new StreamReader(inStream);
                reader = new StreamReader(args.Socket.InputStream.AsStreamForRead());
                System.Diagnostics.Debug.WriteLine("connection................");
                //Read line from the remote client.
                string request = await reader.ReadLineAsync();
                System.Diagnostics.Debug.WriteLine(request);                 
         }
    }
}

回答1:

In addition to what @Hasson said about reading all the lines, you should make sure that you're properly disposing the stream (preferably with a using on the StreamReader, and you could do the same on Stream, although the StreamReader dispose would close it also). It looks like your code is hoping to get the whole message in one call though, so if you don't want to use a while loop that checks !reader.EndOfStream before each ReadLineAsync, you could do something like this:

using (Stream inStream = args.Socket.InputStream.AsStreamForRead())
using (StreamReader reader = new StreamReader(inStream))
{
    System.Diagnostics.Debug.WriteLine("connection................");
    //Read line from the remote client.
    string request = await reader.ReadToEndAsync();
    System.Diagnostics.Debug.WriteLine(request);  
}

I'm also a little worried about the usage of this class. If the code that instantiates a new Connection() doesn't keep a reference to it available, the garbage collector will gobble it all up and your server won't be listening anymore.

For example, if you're having a button click or a page load doing something like this:

Connection conn = new Connection();
conn.Connectie();

Where there isn't some reference to conn maintained, then after that function is done being called, the garbage collector will automatically dispose it and your StreamSocketListener.



回答2:

Your server code is incorrect, you have to keep reading in the SocketListener_ConnectionReceived until there is nothing to read, but here you are reading just one line, think about adding a while loop. there are lots of examples for this kind of loop, for example here.