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