C# TCP 聊天应用线程

标签 c# multithreading sockets tcp p2p

我非常需要帮助。我实际上已经创建了一个程序(将使用)加密来回发送消息。加密部分工作正常,但是我对 Threads 还很陌生,而且我一辈子都无法让应用程序的客户端/服务器部分对齐。聊天程序是使用 TCP 的直接 IP 连接,因此每个主机都是一个客户端和一个服务器。当我调试时,我似乎遇到的问题是,当客户端尝试连接到服务器线程时,服务器线程未准备好,或者如果准备好,它不会放弃线程,以便客户端可以连接!我已经为此工作了几个小时,这非常令人沮丧。我希望有人能提供帮助!我在下面包含了我的代码。 这是我的 MainForm 的代码片段,它构建了客户端和服务器方面:

private void InitializeComponent() {

        server = new ServerSide("127.0.0.1",7865);
        servThread = new Thread(new ThreadStart(server.begin));
        client = new ClientSide("127.0.0.1",7865);
        clientThread = new Thread(new ThreadStart(client.begin));
        servThread.Start();
        clientThread.Start();


        //servThread.Join();
        //clientThread.Join();

这是我的服务器端代码:

public class ServerSide
{
    String IpString;
    int tcpPort;
    bool goodToGo = false;
    System.Net.IPAddress ipAddress = null;
    public ServerSide(String ip, int tcpPort)
    {
        IpString = ip;
        bool isValidIp = System.Net.IPAddress.TryParse(IpString, out ipAddress);
        if (isValidIp == true) // check if the IP is valid, set the bool to true if so
        {
            goodToGo = true;
        }
        else
        {
            goodToGo = false;
        }
    }

    public void begin()
    {
        try
        {
            IPAddress ipAd = IPAddress.Parse(IpString);

            /* Initializes the Listener */
            TcpListener myList = new TcpListener(ipAd, tcpPort);
            Socket s = null;
            /* Start Listening at the specified port */
            while (true)
            {
                myList.Start();

                if (myList.Pending())
                { 
                        s = myList.AcceptSocket();
                         break;
                }

            }

            String toReceive = "";
                    while (true)
                    {
                        byte[] b = new byte[4096];
                        int k = s.Receive(b);
                        for (int i = 0; i < k; i++)
                            toReceive += Convert.ToString((Convert.ToChar(b[i])));

                        // ASCIIEncoding asen = new ASCIIEncoding();

                        var form = MainForm.ActiveForm as MainForm;
                        if (form != null)
                        {
                            form.messageReceived(toReceive);
                        }
                        toReceive = "";
                    }
                }
        catch (Exception e)
        {
            Console.WriteLine("Error..... " + e.StackTrace);
        }
    }
}

客户端代码:

 public class ClientSide
{
    private String IpString;
    private int tcpPort;
    private TcpClient tcpInt;
    private static Stream stm;
    private System.Net.IPAddress ipAddress = null;
    private bool goodToGo = false;

    public ClientSide(String ip, int tcpPort)
    {

        IpString = ip;
        this.tcpPort = tcpPort;

        bool isValidIp = System.Net.IPAddress.TryParse(IpString, out ipAddress);
        if (isValidIp == true)
        {
            goodToGo = true;
        }
        else
        {
            goodToGo = false;
        }
    }

    public void begin()
    {
        try
        {
            tcpInt = new TcpClient();
            // Console.WriteLine("Connecting.....");



            tcpInt.Connect(IpString, tcpPort);
            // use the ipaddress as in the server program

            // Console.WriteLine("Connected");

            // String str = Console.ReadLine();
            stm = tcpInt.GetStream();
        }

        catch (Exception e)
        {
            Console.WriteLine("Error..... " + e.StackTrace);
        }
    }


    public void sendMessage(String str)
    {
      //  stm = tcpInt.GetStream();

        ASCIIEncoding asen = new ASCIIEncoding();
        byte[] ba = asen.GetBytes(str);

        stm.Write(ba, 0, ba.Length);

      /**  byte[] bb = new byte[100];
        int k = stm.Read(bb, 0, 100);

        for (int i = 0; i < k; i++)
            Console.Write(Convert.ToChar(bb[i]));*/

    }
}

再一次.. 通常发生的是我的客户端收到主机主动拒绝连接的错误.. 但我不知道如何计时。我正在寻找如何让我的服务器监听 TCP 连接,但仍然设法转到我的另一个线程来创建 TCP 连接以发送服务器(我目前正在 localhost 上测试它)。 谢谢。

最佳答案

ServerSide 类的构造函数中,您忘记了初始化 tcpPort 成员。因为你忘了,服务端会尝试监听0端口,客户端会尝试连接7865端口,会失败。

尝试将此代码添加到 ServerSide 类的构造函数中。

this.tcpPort = tcpPort;

至于线程,如果客户端线程在服务器线程开始监听之前尝试连接,您可能会遇到问题。您可以使用循环尝试连接多次(假设 10 次),如果不成功则超时(假设 1 秒)。这样,您将重试 10 次并在之后放弃。

关于C# TCP 聊天应用线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10204175/

相关文章:

c - 从 TCP 套接字 C 读取

c# - 使用 C# 代码运行 "Update-Database"Power Shell 命令时出现问题

c# - Android:单击按钮打开新布局并删除当前布局

c# - 如何使用 C# 在没有任何循环的情况下打印 1 到 100

c# - 多线程,锁定和字符串值列表

c# - WPF应用程序在并发环境中被PropertyChangedEventManager挂起

python - Celery Worker 中的多线程

c - 在 Solaris send() 调用中检测损坏的管道

c# - 用c#检查年份是否为闰年

python - 无法使用 Python 读取服务器上的 UDP 数据包