C# UWP应用程序无法使用套接字接收,只能发送

C# UWP应用程序无法使用套接字接收,只能发送,c#,sockets,uwp,streamreader,tcpserver,C#,Sockets,Uwp,Streamreader,Tcpserver,我目前正在开发一个UWP应用程序,它应该能够作为TCP服务器(使用端口),以便客户端可以通过其他设备连接到它,发送请求,服务器用数据响应。 我遵循了上的套接字示例,并获得了示例代码(其中服务器和客户端都在同一个应用程序中) 我更改了IP地址和端口,这样我就可以在两台不同的机器上使用直接连接的应用程序,我还使用 现在的问题如下:UWP应用程序可以成功地与微软的示例提供的自己的客户端方法进行通信,但无法与我制作并在其他平台上运行的控制台客户端程序进行通信。UWP确实可以与客户端连接并发送数据,但它不

我目前正在开发一个UWP应用程序,它应该能够作为TCP服务器(使用端口),以便客户端可以通过其他设备连接到它,发送请求,服务器用数据响应。 我遵循了上的套接字示例,并获得了示例代码(其中服务器和客户端都在同一个应用程序中)

我更改了IP地址和端口,这样我就可以在两台不同的机器上使用直接连接的应用程序,我还使用

现在的问题如下:UWP应用程序可以成功地与微软的示例提供的自己的客户端方法进行通信,但无法与我制作并在其他平台上运行的控制台客户端程序进行通信。UWP确实可以与客户端连接并发送数据,但它不能接收数据,函数为streamReader.readlinesync()将等待无限长的时间,仅此而已。 如何使UWP应用程序获取客户端正在发送的消息,以及我可能做错了什么

public sealed partial class MainPage : Page
{
    static string PORT_NO = "1300";
    const string SERVER_IP = "192.168.0.10";

    public MainPage()
    {
        this.InitializeComponent();
        outputText.Text = "Helloo";
        StartConnection(SERVER_IP, PORT_NO);
        //StartClient();

    }

    public async void StartConnection(string net_aadress, string port_nr)
    {
        try
        {
            var streamSocketListener = new StreamSocketListener();

            // The ConnectionReceived event is raised when connections are received.
            streamSocketListener.ConnectionReceived += this.StreamSocketListener_ConnectionReceived;

            // Start listening for incoming TCP connections on the specified port. You can specify any port that's not currently in use.
            await streamSocketListener.BindServiceNameAsync(port_nr);

            outputText.Text = "server is listening...";
        }
        catch (Exception ex)
        {
            Windows.Networking.Sockets.SocketErrorStatus webErrorStatus = Windows.Networking.Sockets.SocketError.GetStatus(ex.GetBaseException().HResult);
            outputText.Text = (webErrorStatus.ToString() != "Unknown" ? webErrorStatus.ToString() : ex.Message);
        }
    }

    private async void StreamSocketListener_ConnectionReceived(Windows.Networking.Sockets.StreamSocketListener sender, Windows.Networking.Sockets.StreamSocketListenerConnectionReceivedEventArgs args)
    {

        string request = "password";
        string second;
        /*
        using (var streamReader = new StreamReader(args.Socket.InputStream.AsStreamForRead()))
        {
            request = await streamReader.ReadLineAsync();
        }
        */
        //await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => this.serverListBox.Items.Add(string.Format("server received the request: \"{0}\"", request)));

        // Echo the request back as the response.
        using (Stream outputStream = args.Socket.OutputStream.AsStreamForWrite())
        {
            using (var streamWriter = new StreamWriter(outputStream))
            {
                await streamWriter.WriteLineAsync(request);
                await streamWriter.FlushAsync();
            }
        }

        using (var streamReader = new StreamReader(args.Socket.InputStream.AsStreamForRead()))
        {
            second = await streamReader.ReadLineAsync();
        }


        using (Stream outputStream = args.Socket.OutputStream.AsStreamForWrite())
        {
            using (var streamWriter = new StreamWriter(outputStream))
            {
                await streamWriter.WriteLineAsync(second);
                await streamWriter.FlushAsync();
            }
        }

        //await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => this.serverListBox.Items.Add(string.Format("server sent back the response: \"{0}\"", request)));

        sender.Dispose();

        //await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => this.serverListBox.Items.Add("server closed its socket"));
    }

    private async void StartClient()
    {
        try
        {
            // Create the StreamSocket and establish a connection to the echo server.
            using (var streamSocket = new Windows.Networking.Sockets.StreamSocket())
            {
                // The server hostname that we will be establishing a connection to. In this example, the server and client are in the same process.
                var hostName = new Windows.Networking.HostName("localhost");

                //this.clientListBox.Items.Add("client is trying to connect...");

                await streamSocket.ConnectAsync(hostName, PORT_NO);

                //this.clientListBox.Items.Add("client connected");

                // Send a request to the echo server.
                string request = "Hello, World!";
                using (Stream outputStream = streamSocket.OutputStream.AsStreamForWrite())
                {
                    using (var streamWriter = new StreamWriter(outputStream))
                    {
                        await streamWriter.WriteLineAsync(request);
                        await streamWriter.FlushAsync();
                    }
                }

                //this.clientListBox.Items.Add(string.Format("client sent the request: \"{0}\"", request));

                // Read data from the echo server.
                string response;
                using (Stream inputStream = streamSocket.InputStream.AsStreamForRead())
                {
                    using (StreamReader streamReader = new StreamReader(inputStream))
                    {
                        response = await streamReader.ReadLineAsync();
                    }
                }

                await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                     () =>
                     {
                         outputText.Text = "Client got back " + response;
                     }
                 );



            }

            //this.clientListBox.Items.Add("client closed its socket");
        }
        catch (Exception ex)
        {
            Windows.Networking.Sockets.SocketErrorStatus webErrorStatus = Windows.Networking.Sockets.SocketError.GetStatus(ex.GetBaseException().HResult);
            //this.clientListBox.Items.Add(webErrorStatus.ToString() != "Unknown" ? webErrorStatus.ToString() : ex.Message);
        }
    }


}
以下是客户端应用程序的源代码:

{
class Program
{
    const int PORT_NUMBER = 1300;
    const string SERVER_IP = "192.168.0.10";
    static void Main(string[] args)
    {
        string textToSend = DateTime.Now.ToString();
        string password = "Madis on loll";
        string receiveddata;
        try
        {
            Console.WriteLine("Client progrm started");
            TcpClient client = new TcpClient(SERVER_IP, PORT_NUMBER);
            NetworkStream nwStream = client.GetStream();

            //System.Threading.Thread.Sleep(500);
            //see, how long is packet

            byte[] bytesToRead = new byte[client.ReceiveBufferSize];
            int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
            Console.WriteLine("Received : " + Encoding.ASCII.GetString(bytesToRead, 0, bytesRead));


            byte[] password2 = ASCIIEncoding.ASCII.GetBytes(password);
            Console.WriteLine("Sending : " + password);
            nwStream.Write(password2, 0, password2.Length); //sending packet

            byte[] receiveddata2 = new byte[client.ReceiveBufferSize];
            int receiveddatalength = nwStream.Read(receiveddata2, 0, client.ReceiveBufferSize);
            Console.WriteLine("Received : " + Encoding.ASCII.GetString(receiveddata2, 0, bytesRead));


        }
        catch (Exception ex)
        {
            Console.WriteLine("Connection  error");
        }
    }

}

}

我自己找到了答案:服务器程序中的ReadLineAsync()存在主要问题:它等待并收集所有流,直到获得行尾字符。在这种情况下,行尾从未被发送,所以服务器一直在无限期地等待。 最简单的修复方法是在客户端,只需在数据包末尾添加行尾,如下所示:

之前:

byte[] password2 = ASCIIEncoding.ASCII.GetBytes(password);
Console.WriteLine("Sending : " + password);
nwStream.Write(password2, 0, password2.Length); //sending packet
之后:

byte[] newLine = Encoding.ASCII.GetBytes(Environment.NewLine);   
byte[] password2 = ASCIIEncoding.ASCII.GetBytes(password);
Console.WriteLine("Sending : " + password);
nwStream.Write(password2, 0, password2.Length); //sending packet
nwStream.Write(newLine,0,newLine.Length);
Stream outputStream = args.Socket.OutputStream.AsStreamForWrite();
var streamWriter = new StreamWriter(outputStream);

streamWriter.AutoFlush = true;
await streamWriter.WriteLineAsync(request);
还有一件值得一提的事情:当前StreamSocketListener_ConnectionReceived只能发送一次,然后它将outputStream.CanWrite设置为false。 这可以通过从写入和读取函数中删除using()来解决,如下所示: 之前:

PS!手动冲洗也被自动冲洗取代

using (Stream outputStream = args.Socket.OutputStream.AsStreamForWrite())
    {
        using (var streamWriter = new StreamWriter(outputStream))
        {
            await streamWriter.WriteLineAsync(request);
            await streamWriter.FlushAsync();
        }
    }
之后:

byte[] newLine = Encoding.ASCII.GetBytes(Environment.NewLine);   
byte[] password2 = ASCIIEncoding.ASCII.GetBytes(password);
Console.WriteLine("Sending : " + password);
nwStream.Write(password2, 0, password2.Length); //sending packet
nwStream.Write(newLine,0,newLine.Length);
Stream outputStream = args.Socket.OutputStream.AsStreamForWrite();
var streamWriter = new StreamWriter(outputStream);

streamWriter.AutoFlush = true;
await streamWriter.WriteLineAsync(request);

希望有一天它能帮助别人。

您调试了服务器并找到代码停止的地方了吗?我不喜欢“使用”语句,因为它们不会报告所有异常。我宁愿使用try/catch块来正确地报告所有异常。我打赌您会发现,您得到的异常是未报告的服务器。自己调试服务器代码。感谢您的回答,是的,我调试了服务器代码,它正在streamReader.ReadLineAsync()上停止;函数,等待无法从控制台应用程序获取的数据。默认情况下,Microsoft建议在客户端和服务器的UWP SAMD附加write语句中使用Using语句,如“outputText.Text=“server is listening…”,并在输出消息中包含时间。你可能会收到一条消息,当你收到第二条消息时会被卡住。事实上,这两个应用程序的第一个版本是:客户端在连接后发送消息,而服务器最初只接收消息。在那个场景中,服务器在建立连接后一直在无限期地等待,所以即使是第一条消息也并没有进入服务器