首页 > 解决方案 > UWP StreamSocket 客户端在较大数据传输后未收到响应

问题描述

我有一个使用套接字的 WPF“服务器”应用程序,以及一个使用 StreamSocket 的 UWP“客户端”应用程序。我可以很好地传输少量数据,但如果我尝试发送 288kb 文件,WPF 应用程序可以正常接收该文件,但 UWP 应用程序永远不会收到响应。

WPF代码:在ReadCallback方法中,内容以command;printername{data}的格式发送。数据全部接收正常,但未接收到在处理数据之前调用的 Send 方法。

public void Start()
        {
            Task.Run(() =>
            {
                var ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
                var ipAddress = ipHostInfo.AddressList.FirstOrDefault(x =>x.AddressFamily == AddressFamily.InterNetwork);
                var localEndPoint = new IPEndPoint(ipAddress, Settings.Default.PrintPort);

                listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                try
                {
                    listener.Bind(localEndPoint);
                    listener.Listen(100);
                    IsRunning = true;
                    while (true)
                    {

                        // Set the event to nonsignaled state.  
                        AllDone.Reset();

                        // Start an asynchronous socket to listen for connections.  
                        listener.BeginAccept(
                            AcceptCallback,
                            listener);

                        // Wait until a connection is made before continuing.  
                        AllDone.WaitOne();


                    }

                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
            });
        }
public void AcceptCallback(IAsyncResult ar)
        {
            if(!IsRunning) return;

            // Signal the main thread to continue.  
            AllDone.Set();

            // Get the socket that handles the client request. 
            Socket handler = listener.EndAccept(ar);

            // Create the state object.  
            StateObject state = new StateObject {WorkSocket = handler};
            handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0,
                ReadCallback, state);
        }
public static void ReadCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the state object and the handler socket  
                // from the asynchronous state object.  
                StateObject state = (StateObject)ar.AsyncState;
                Socket handler = state.WorkSocket;

                // Read data from the client socket.   
                int bytesRead = handler.EndReceive(ar);

                if (bytesRead > 0)
                {
                    // There  might be more data, so store the data received so far.  
                    state.Sb.Append(Encoding.ASCII.GetString(
                        state.Buffer, 0, bytesRead));

                    // Check for end-of-file tag. If it is not there, read   
                    // more data.  
                    var content = state.Sb.ToString();


                    if (content.IndexOf("<EOF>") > -1)
                    {
                        content = content.Remove(content.IndexOf("<EOF>"));
                        if (content.StartsWith("PrintFile"))
                        {
                            if (!content.Contains("{"))
                            {
                                Send(handler, "false");
                                return;
                            }
                            var parts = content.Substring(0, content.IndexOf('{')).Split(';');
                            if (string.IsNullOrEmpty(parts[1]))
                            {
                                Send(handler, "false");
                                return;
                            }
                            // This send never gets received
                            Send(handler, "true");
                            //But the file is printed
                            var base64 = content.Substring(content.IndexOf('{') + 1);
                            base64 = base64.Remove(base64.LastIndexOf('}'));
                            var doc = new Spire.Pdf.PdfDocument(Convert.FromBase64String(base64));
                            doc.PrintSettings.PrinterName = parts[1];
                            doc.Print();
                        }
                    }
                    else
                    {
                        // Not all data received. Get more.  
                        handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0,
                            ReadCallback, state);
                    }
                }

            }
            catch
            {
                //Ignore
            }
        }

private static void Send(Socket handler, String data)
        {
            // Convert the string data to byte data using ASCII encoding.  
            byte[] byteData = Encoding.ASCII.GetBytes(data);

            // Begin sending the data to the remote device.  
            handler.BeginSend(byteData, 0, byteData.Length, 0,
                SendCallback, handler);
        }

        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.  
                Socket handler = (Socket)ar.AsyncState;
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

UWP 代码:

 public bool PrintFlle(string printer, string base64)
        {
            try
            {
                var result = Send($"PrintFile;{printer}{{{base64}}}<EOF>").Result;
                return bool.TryParse(result, out var b) && b;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
            finally
            {
                socket.Dispose();
            }
        }



        private async Task<string> Send(string input)
        {
            try
            {
                socket = new StreamSocket();

                await socket.ConnectAsync(HostName, App.LocalSettings.Values["PrintPort"] as string);
                using (Stream outputStream = socket.OutputStream.AsStreamForWrite())
                {
                    using (var streamWriter = new StreamWriter(outputStream))
                    {
                        await streamWriter.WriteLineAsync(input);
                        await streamWriter.FlushAsync();
                    }
                }

                using (Stream inputStream = socket.InputStream.AsStreamForRead())
                {
                    using (StreamReader streamReader = new StreamReader(inputStream))
                    {
                        var output = await streamReader.ReadLineAsync();
                        socket.Dispose();
                        return output;
                    }
                }
            }
            catch (Exception e)
            {
                socket.Dispose();
                return "";
            }
        }

标签: c#wpfsocketsuwp

解决方案


推荐阅读