Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C语言中使用Socket进行通信时遇到的问题#_C#_Sockets_Communication - Fatal编程技术网

C# 在C语言中使用Socket进行通信时遇到的问题#

C# 在C语言中使用Socket进行通信时遇到的问题#,c#,sockets,communication,C#,Sockets,Communication,我希望我没有错过一些愚蠢的事情。我正在开发一个应用程序,它可以在许多手持window的移动计算机和中央服务器之间进行通信。当前的体系结构只允许短消息(最多4096字节),我正在修改应用程序,以便在必要时允许更大的通信。此代码似乎间歇性工作,具体取决于服务器的速度和网络通信速度。我需要找到一种方法使服务器的接收代码更加可靠。它有时工作正常,但有时手持设备会抛出错误“无法将数据写入传输连接。远程主机强制关闭了现有连接。” 手持式传输代码: public bool SendMessage(Networ

我希望我没有错过一些愚蠢的事情。我正在开发一个应用程序,它可以在许多手持window的移动计算机和中央服务器之间进行通信。当前的体系结构只允许短消息(最多4096字节),我正在修改应用程序,以便在必要时允许更大的通信。此代码似乎间歇性工作,具体取决于服务器的速度和网络通信速度。我需要找到一种方法使服务器的接收代码更加可靠。它有时工作正常,但有时手持设备会抛出错误“无法将数据写入传输连接。远程主机强制关闭了现有连接。”

手持式传输代码:

public bool SendMessage(NetworkStream ansStream, string asMessage)  
{  
    try  
    {  
        Byte[] wBytes = System.Text.Encoding.ASCII.GetBytes(asMessage.ToCharArray());  
        ansStream.Write(wBytes, 0, wBytes.Length);  
        return true;  
    }  
    catch (Exception E)  
    {  
        MessageBox.Show(E.Message, "Network Error");  
        return false;  
    }  
}  
public const int BUFFER_LENGTH = 4096;  
public void ProcessMessage(object aClient)  
{  
    TcpClient wClient = (aClient as TcpClient);  
    try  
    {  
        byte[] wBytes = new byte[BUFFER_LENGTH];  
        StringBuilder wMessage = new StringBuilder();  
        using (NetworkStream wNetStream = wClient.GetStream())  
        {  
            try  
            {  
                int wiRead = 0;  
                int wiTotalBytes = 0;  
                do  
                {  
                    wiRead = wNetStream.Read(wBytes, 0, wBytes.Length);  
                    wMessage.AppendFormat("{0}", Encoding.ASCII.GetString(wBytes, 0, wiRead));  
                    wiTotalBytes += wiRead;  

                    // my attempt to ensure entire message is read  
                    if (wNetStream.DataAvailable)  
                    {  
                        Thread.Sleep(1000);  
                    }  

                } while (wNetStream.DataAvailable);  

                if (wiTotalBytes > 0)  
                {  
                    string wsAnswerFile = "";  
                    string wsResult = DoBusinessProcess(wMessage.ToString(), out wsAnswerFile);  
                    if (string.IsNullOrEmpty(wsAnswerFile))  
                    {  
                        wBytes = Encoding.ASCII.GetBytes(wsResult);  
                        wNetStream.Write(wBytes, 0, wBytes.Length);  
                    }  
                    else  
                    {  
                        if (File.Exists(wsAnswerFile))  
                        {  
                            SendFile(wsAnswerFile, wNetStream);  
                        }  
                    }  
                }  
            }  
            catch (Exception E)  
            {  
                MessageBox.Show(E.Message, "Network Error");  
            }  
            finally  
            {  
                if (wNetStream != null)  
                {  
                    wNetStream.Close();  
                }  
            }  
        }  
    }  
}  
服务器端接收代码:

public bool SendMessage(NetworkStream ansStream, string asMessage)  
{  
    try  
    {  
        Byte[] wBytes = System.Text.Encoding.ASCII.GetBytes(asMessage.ToCharArray());  
        ansStream.Write(wBytes, 0, wBytes.Length);  
        return true;  
    }  
    catch (Exception E)  
    {  
        MessageBox.Show(E.Message, "Network Error");  
        return false;  
    }  
}  
public const int BUFFER_LENGTH = 4096;  
public void ProcessMessage(object aClient)  
{  
    TcpClient wClient = (aClient as TcpClient);  
    try  
    {  
        byte[] wBytes = new byte[BUFFER_LENGTH];  
        StringBuilder wMessage = new StringBuilder();  
        using (NetworkStream wNetStream = wClient.GetStream())  
        {  
            try  
            {  
                int wiRead = 0;  
                int wiTotalBytes = 0;  
                do  
                {  
                    wiRead = wNetStream.Read(wBytes, 0, wBytes.Length);  
                    wMessage.AppendFormat("{0}", Encoding.ASCII.GetString(wBytes, 0, wiRead));  
                    wiTotalBytes += wiRead;  

                    // my attempt to ensure entire message is read  
                    if (wNetStream.DataAvailable)  
                    {  
                        Thread.Sleep(1000);  
                    }  

                } while (wNetStream.DataAvailable);  

                if (wiTotalBytes > 0)  
                {  
                    string wsAnswerFile = "";  
                    string wsResult = DoBusinessProcess(wMessage.ToString(), out wsAnswerFile);  
                    if (string.IsNullOrEmpty(wsAnswerFile))  
                    {  
                        wBytes = Encoding.ASCII.GetBytes(wsResult);  
                        wNetStream.Write(wBytes, 0, wBytes.Length);  
                    }  
                    else  
                    {  
                        if (File.Exists(wsAnswerFile))  
                        {  
                            SendFile(wsAnswerFile, wNetStream);  
                        }  
                    }  
                }  
            }  
            catch (Exception E)  
            {  
                MessageBox.Show(E.Message, "Network Error");  
            }  
            finally  
            {  
                if (wNetStream != null)  
                {  
                    wNetStream.Close();  
                }  
            }  
        }  
    }  
}  

调用ProcessMessage并向其传递TCPClient时,如何初始化这些TCPClient连接?如果在没有多线程的循环中执行,那么可能会得到与前面解释的结果类似的结果。当然,如果不知道客户机侦听循环是如何设置的,我就不能确定

查看此链接: 第二个代码片段显示了一个侦听器循环,它将为每个客户端启动一个新线程。如果您没有为每个客户机启动新线程,如果在您从另一个客户机接收数据时,有一个新的客户机正在尝试连接,它会说服务器无法响应


我希望这有帮助

网络错误很常见,您必须编写代码才能避免它们。。。是否每次要发送消息时都要打开和关闭套接字?否则,我不知道如何识别消息边界。另一方面,有点奇怪,您有一个ProcessMessage方法,但实现仍在使用流…是的,我遗漏了这一部分。客户端是在一个循环中声明的,该循环打开侦听器并将客户端发送到一个新线程。多亏了这些想法,我以后可能会回到这种方法,但我已经对客户端进行了设计,使其以小消息的形式发送数据,而不是一次性发送整个文件。是的,TcpClient在为每个连接创建新线程的循环中初始化。感谢您提供该示例的链接,我将修改我的代码以使用“读取到接收到0字节”模型。这与我自己在谷歌上找到的MSDN答案相符。我已经尝试了这两种方法。。。while(DataAvailable)方法和直到0字节的读取方法以及do。。。while是有效的方法。问题是对于较长的通信,循环与Thread.Sleep(1000)行可靠地工作,我希望能够在没有睡眠的情况下读取所有内容,这会降低对较短请求的响应速度。有没有想过我错过了什么?