C# TCP 聊天应用程序线程

本文关键字:线程 应用程序 聊天 TCP | 更新日期: 2023-09-27 18:31:32

我迫切需要帮助。我基本上创建了一个程序,该程序(将使用)加密来回发送消息。加密部分工作正常,但是我对线程相当陌生,我一生都无法让我的应用程序的客户端/服务器部分对齐。聊天程序是使用 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 连接以发送服务器(我目前正在本地主机上对此进行测试)。谢谢。

C# TCP 聊天应用程序线程

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

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

this.tcpPort = tcpPort;
至于线程,

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