C# TCP聊天客户端/服务器无法在本地主机上工作

C# TCP聊天客户端/服务器无法在本地主机上工作,c#,windows,chat,server,C#,Windows,Chat,Server,我目前正在学习编写一个使用服务器的聊天室应用程序。到目前为止,如果我在一台机器上运行服务器和应用程序的多个实例,一切都正常。当我尝试在一台计算机上运行服务器,并从另一台计算机上运行实际的聊天应用程序时,我会收到一个异常,该异常读取连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立的连接失败,因为连接的主机未能响应Ipaddressport 服务器端代码: using System; using System.Net; using System.Net.Sockets; using Sys

我目前正在学习编写一个使用服务器的聊天室应用程序。到目前为止,如果我在一台机器上运行服务器和应用程序的多个实例,一切都正常。当我尝试在一台计算机上运行服务器,并从另一台计算机上运行实际的聊天应用程序时,我会收到一个异常,该异常读取连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立的连接失败,因为连接的主机未能响应Ipaddressport

服务器端代码:

using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Collections;
using System.Text;
using System.Threading;

namespace ChatAppServer
{
    class Program
    {
        public static Hashtable ClientList = new Hashtable(); 
        const int PORT = 321;
        string localIp;


        static void Main(string[] args)
        {


            TcpListener sckServer = new TcpListener(PORT);
            TcpClient sckClient = default(TcpClient);
            int counter = 0;

            sckServer.Start();
            Console.WriteLine("Chat Server is now Running ....");
            counter = 0;
            //Parser myParser = new Parser();
            while (true)
            {
                counter = counter + 1;
                sckClient = sckServer.AcceptTcpClient();

                string clientData = "";
                byte[] recieveData = new byte[10025]; 

                NetworkStream netStream = sckClient.GetStream();
                netStream.Read(recieveData, 0, (int)sckClient.ReceiveBufferSize);
                clientData = System.Text.Encoding.ASCII.GetString(recieveData);
                clientData = clientData.Substring(0, clientData.IndexOf("$"));

                ClientList.Add(clientData, sckClient);

                Broadcast(clientData + " joined the chat", clientData, false);

                Console.WriteLine(clientData + " connected to the chat");
                handleClient client = new handleClient();
                client.ClientStart(sckClient, clientData, ClientList);
            }
            sckClient.Close();
            sckServer.Stop();
            Console.WriteLine("exit");
            Console.ReadLine();
        }


        public static void Broadcast(string msg, string userName, bool flag)
        {
            foreach (DictionaryEntry Item in ClientList)
            {
                TcpClient sckBroadcast;
                sckBroadcast = (TcpClient)Item.Value;
                NetworkStream broadcastStream = sckBroadcast.GetStream();
                Byte[] broadcastData = null;

                if (flag == true)
                {
                    broadcastData = Encoding.ASCII.GetBytes(userName + ": " + msg);
                }
                else 
                {
                    broadcastData = Encoding.ASCII.GetBytes(msg);
                }
                broadcastStream.Write(broadcastData, 0, broadcastData.Length);
                broadcastStream.Flush();
            }
        }

        public class handleClient
        {
            TcpClient sckClient;
            string clId;
            Hashtable ClientList;

            public void ClientStart(TcpClient inSckClient, string clientId, Hashtable clist) {
                this.sckClient = inSckClient;
                this.clId = clientId;
                this.ClientList = clist;
                Thread ctThread = new Thread(runChat);
                ctThread.Start();
            }
            private void runChat() {
                int requestCount = 0;
                byte[] recieveData = new byte[10025];
                string clientData = "";
                string rCount = null;

                while ((true))
                {
                    try
                    {
                        requestCount += 1;
                        NetworkStream netStream = sckClient.GetStream();
                        netStream.Read(recieveData, 0, (int)sckClient.ReceiveBufferSize);
                        clientData = System.Text.Encoding.ASCII.GetString(recieveData);
                        clientData = clientData.Substring(0, clientData.IndexOf("$"));
                        Console.WriteLine(clId + " : " + clientData);
                        rCount = Convert.ToString(requestCount);

                        Program.Broadcast(clientData, clId, true);


                    }
                    catch(Exception ex) 
                    {
                        Console.WriteLine(ex.ToString());
                    }
                }
            }

        }
    }
}
聊天室应用程序代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
//Need for the application
using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace ChatApp
{
    public partial class Form1 : Form
    {
        System.Net.Sockets.TcpClient sckClient = new System.Net.Sockets.TcpClient();
        NetworkStream svrStream = default(NetworkStream);
        string recieveData = null;

        public Form1()
        {
            InitializeComponent();
            btnSend.Enabled = false;
        }
        private void btnConnect_Click(object sender, EventArgs e)
        {
            recieveData = "Connected to Server";
            msg();
            int serverPort = Convert.ToInt32(txtServerPort.Text);
            sckClient.Connect(txtServerIp.Text, serverPort);
            svrStream = sckClient.GetStream();

            byte[] outStream = System.Text.Encoding.ASCII.GetBytes(txtUserName.Text + "$");
            svrStream.Write(outStream, 0, outStream.Length);
            svrStream.Flush();

            Thread ctThread = new Thread(MessageCallBack);
            btnSend.Enabled = true;
            btnConnect.Enabled = false;
            txtUserName.Enabled = false;
            txtServerIp.Enabled = false;
            txtServerPort.Enabled = false;
            ctThread.Start();

        }

        private void MessageCallBack()
        {
            while(true)
            {
                svrStream = sckClient.GetStream();
                int buffSize = 0;
                byte[] inStream = new byte[10025];
                buffSize = sckClient.ReceiveBufferSize;
                svrStream.Read(inStream, 0, buffSize);
                string returnData = System.Text.Encoding.ASCII.GetString(inStream);
                recieveData = "" + returnData;
                msg();
            }
        }
        //function to display data strings 
        private void msg()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(msg));
            }
            else
            {
                lstMessage.Items.Add(recieveData);
            }
        }



        private void btnSend_Click(object sender, EventArgs e)
        {
            byte[] outStream = System.Text.Encoding.ASCII.GetBytes(txtMessage.Text + "$");
            svrStream.Write(outStream, 0, outStream.Length);
            svrStream.Flush();
            txtMessage.Text = "";
        }

我对您的代码有两个问题:

不要使用.ReceiveBufferSize值,因为它是字节数组长度的不同值。您可以有一个索引超出范围的异常

服务器端存在并发问题。有多个线程尝试访问ClientList,但此集合不是线程安全的

要解决此问题,可以使用lock关键字

因为你是初学者,我会给你一些建议

尝试比原始线程更好地使用异步网络函数。 在C语言中有很多关于安全性的教程,其中有一些比lock关键字更好的东西。
正确的IP?防火墙关闭了吗?您是否仅在本地主机上侦听?您连接的IP和端口是什么?顺便说一下,欢迎来到StackOverflow!这听起来像是您的计算机防火墙的问题,或者使用计算机以外的计算机的IP不正确,但在本地网络上需要192.168.0.X IP,通常是远程计算机上已在使用的端口server@MethodMan如果端口已在使用,则会出现不同的错误消息。我更改了一些代码,现在收到错误消息:无法建立连接,因为目标计算机主动拒绝它。。。我更改的行是TcpListener sckServer=新的TcpListenerPORT;to TcpListener sckServer=新TcpListener127.0.0.1,端口;
private static object _lock = new object();
//...
lock (_lock)
{
     ClientList.Add(clientData, sckClient);
}

lock (_lock)
{
     Broadcast(clientData + " joined the chat", clientData, false);
}
//...
lock (_lock)
{
     Program.Broadcast(clientData, clId, true);

}