C#多用户Tcp / Ip聊天应用程序

时间:2019-01-13 16:09:47

标签: c# tcp backgroundworker

我计划编写一个可以用作服务器或客户端的C#应用​​程序。我实现了两个WinForm。第一个名为ServerChat的服务器,在加载时调用backgroundWorker

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    serverSocket.Start();
    try
    {
        clientSocket = serverSocket.AcceptTcpClient();
        backgroundWorker1.ReportProgress(0, clientSocket);
    }
    catch (Exception exp)
    {
        throw exp;
    }
}

private void backgroundWorker1_ProgressChanged(object sender,
    System.ComponentModel.ProgressChangedEventArgs e)
{
    if (e.UserState!=null)
    {
        try
        {
            frmChatClient = new frmChatClient("server", clientSocket);
            frmChatClient.Show();
        }
        catch (Exception exp)
        {
            throw exp;
        }
    }
}

如您所见,当连接被接受时,frmChatClient显示了对于先前传入的读取套接字具有自己的backgroundWorker。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    byte[] bytesFrom = new byte[10025];

    while (true)
    {
        try
        {
           // in this line clientSocket is connected
            this.networkStream = clientSocket.GetStream();

           // this line throw exeotion
           networkStream.Read(bytesFrom, 0, textbox1.MaxLength);

            dataFromClient = System.Text.Encoding.BigEndianUnicode.GetString(bytesFrom);

            backgroundWorker1.ReportProgress(0,dataFromClient);
           // break;
        }
        catch (Exception ex)
        {
            throw ex;

        }
    }
}

尝试读取或写入后,出现以下错误消息

  

无法从传输连接中读取数据:远程主机强行关闭了现有连接。

1 个答案:

答案 0 :(得分:2)

连接已关闭,因为未产生任何流量。如果是这样,套接字将关闭连接。

TcpClient设计用于发送/接收然后关闭。它对其底层套接字没有灵活性。可以使用AcceptSocket来获取接受的连接,而不使用AcceptTcpClient,然后使用TCP keep alive使连接保持连接状态。或者,如果要使用TcpClient,请确保发送保持活动的数据包。

在您的协议上,您可以提供一个带有少量占用空间的ALIVE数据包,仅用于通知服务器和客户端连接仍处于正常状态。发送这些类型的数据包而不是标准的TCP Keep Alive有利有弊。但是肯定会使您的客户保持联系。