Проблема в общении с использованием сокета в C # - PullRequest
0 голосов
/ 12 апреля 2011

Я надеюсь, что не пропустил что-то глупое. Я работаю над приложением, которое обменивается данными между несколькими мобильными компьютерами портативного окна и центральным сервером. Текущая архитектура допускает только короткие сообщения (до 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();  
                }  
            }  
        }  
    }  
}  

1 Ответ

0 голосов
/ 12 апреля 2011

Когда вы вызываете ProcessMessage и передаете ему TCPClient, как вы инициализируете эти соединения TCPCLient? Если вы делаете это в цикле без многопоточности, вы можете получить результаты, подобные тем, которые вы объяснили. Конечно, я не могу быть уверен, не зная, как настроен твой цикл прослушивания клиента.

Проверьте эту ссылку: http://www.switchonthecode.com/tutorials/csharp-tutorial-simple-threaded-tcp-server Второй фрагмент кода показывает цикл слушателя, который запускает новый поток для каждого клиента. Если вы не запускаете новый поток для каждого клиента, если новый пытается подключиться, когда вы получаете данные от другого, он скажет, что сервер не может ответить.

Надеюсь, это поможет!

...