我正面临着一个奇怪的问题,我写了一个简单的聊天应用程序,当我在一台机器上启动2个客户端但是当我在我的笔记本电脑上尝试一个(其他电脑但是同一个ip)或将其发送给我朋友,它只是不工作......我们都关闭了防火墙
那是服务器代码(我认为可能是问题的一部分)
private void StartListening()
{
listener = new TcpListener(IPAddress.Any, listenport);
listener.Start();
while (true) {
try
{
Socket s = listener.AcceptSocket();
clientsocket = s;
clientservice = new Thread(new ThreadStart(ServiceClient));
clientservice.Start();
}
catch(Exception e)
{
Console.WriteLine(e.ToString() );
}
}
//listener.Stop();
}
这就是客户端代码
private void EstablishConnection()
{
statusBar1.Text = "Connecting to Server";
try
{
clientsocket = new TcpClient("10.0.0.3",serverport);
ns = clientsocket.GetStream();
sr = new StreamReader(ns);
connected = true;
}
catch (Exception e)
{
MessageBox.Show("Could not connect to Server","Error",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
statusBar1.Text = "Disconnected";
}
}
private void RegisterWithServer()
{
try
{
string command = "CONN|" + ChatOut.Text;
Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray());
ns.Write(outbytes,0,outbytes.Length);
string serverresponse = sr.ReadLine();
serverresponse.Trim();
string[] tokens = serverresponse.Split(new Char[]{'|'});
if(tokens[0] == "LIST")
{
statusBar1.Text = "Connected";
btnDisconnect.Enabled = true;
}
for(int n=1; n<tokens.Length-1; n++)
lbChatters.Items.Add(tokens[n].Trim(new char[]{'\r','\n'}));
this.Text = clientname + ": Connected to Chat Server";
}
catch (Exception e)
{
MessageBox.Show("Error Registering","Error",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
private void ReceiveChat()
{
bool keepalive = true;
while (keepalive)
{
try
{
Byte[] buffer = new Byte[2048];
ns.Read(buffer,0,buffer.Length);
string chatter = System.Text.Encoding.ASCII.GetString(buffer);
string[] tokens = chatter.Split(new Char[]{'|'});
if (tokens[0] == "CHAT")
{
rtbChatIn.AppendText(tokens[1]);
if(logging)
logwriter.WriteLine(tokens[1]);
}
if (tokens[0] == "PRIV") {
rtbChatIn.AppendText("Private from ");
rtbChatIn.AppendText(tokens[1].Trim() );
rtbChatIn.AppendText(tokens[2] + "\r\n");
if(logging){
logwriter.Write("Private from ");
logwriter.Write(tokens[1].Trim() );
logwriter.WriteLine(tokens[2] + "\r\n");
}
}
if (tokens[0] == "JOIN")
{
rtbChatIn.AppendText(tokens[1].Trim() );
rtbChatIn.AppendText(" has joined the Chat\r\n");
if(logging){
logwriter.WriteLine(tokens[1]+" has joined the Chat");
}
string newguy = tokens[1].Trim(new char[]{'\r','\n'});
lbChatters.Items.Add(newguy);
}
if (tokens[0] == "GONE")
{
rtbChatIn.AppendText(tokens[1].Trim() );
rtbChatIn.AppendText(" has left the Chat\r\n");
if(logging){
logwriter.WriteLine(tokens[1]+" has left the Chat");
}
lbChatters.Items.Remove(tokens[1].Trim(new char[]{'\r','\n'}));
}
if (tokens[0] == "QUIT")
{
ns.Close();
clientsocket.Close();
keepalive = false;
statusBar1.Text = "Server has stopped";
connected= false;
btnSend.Enabled = false;
btnDisconnect.Enabled = false;
}
}
catch(Exception e){}
}
}
private void QuitChat()
{
if(connected) {
try{
string command = "GONE|" + clientname;
Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray());
ns.Write(outbytes,0,outbytes.Length);
clientsocket.Close();
}
catch(Exception ex){
}
}
if(logging)
logwriter.Close();
if(receive != null && receive.IsAlive)
receive.Abort();
this.Text = "ChatClient";
}
private void StartStopLogging()
{
if(!logging){
if(!Directory.Exists("logs"))
Directory.CreateDirectory("logs");
string fname = "logs\\" + DateTime.Now.ToString("ddMMyyHHmm") + ".txt";
logwriter = new StreamWriter(new FileStream(fname, FileMode.OpenOrCreate,
FileAccess.Write));
logging = true;
btnLog.Text = "Stop Logging";
statusBar1.Text = "Connected - Log on";
}
else{
logwriter.Close();
logging = false;
btnLog.Text = "Start Logging";
statusBar1.Text = "Connected - Log off";
}
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(String[] args)
{
ChatClientForm cf = new ChatClientForm();
if(args.Length == 0)
cf.serveraddress = "localhost";
else
cf.serveraddress = args[0];
Application.Run(cf);
}
private void btnConnect_Click(object sender, System.EventArgs e)
{
if(ChatOut.Text == ""){
MessageBox.Show("Enter a name in the box before connecting","Error",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
else
clientname = ChatOut.Text;
EstablishConnection();
if(connected)
{
RegisterWithServer();
receive = new Thread(new ThreadStart(ReceiveChat));
receive.Start();
btnSend.Enabled = true;
btnConnect.Enabled = false;
ChatOut.Text = "";
}
我用2个星期的时间打破了我的头......请有人帮忙...... :(
答案 0 :(得分:1)
基本上你的网络上有一个设备(可能是10.0.01或10.0.0.254,但它可能是其他东西)。这可能是您的路由器/ cablemodem / dsl调制解调器。这允许您进行网络地址转换/端口地址转换(NAT / PAT)。这允许您与LAN上的所有计算机(79.181.175.247
)共享1个公共/ WAN IP地址(10.0.0.*
)。它通过重新映射出站的所有连接来共享一个地址,并跟踪所有这些连接。因此,当您的计算机外出连接到互联网(比如浏览网站)。它从10.0.0.3端口45356连接到google.com端口80.防火墙然后将请求映射到来自79.181.175.247端口5634并将数据包发送到谷歌,并跟踪返回到端口5634的流量映射到10.0 .0.3端口45356,因此它将其发送回请求主机。
副作用是入站连接不知道去哪里。因此,例如,如果您的聊天程序中的服务器端口是1234,并且它正在监听您的笔记本电脑的0.0.0.0(10.0.0.3)。你的防火墙/路由器(10.0.0.1?)不知道这个端口(有一些机制,比如UPNP可以将它传送到兼容的路由器,但这不在此范围之内)。因此,您需要手动告诉路由器/防火墙,端口1234上公共IP地址上的任何连接都应转发到笔记本电脑上的端口1234。根据防火墙/路由器,它可以有不同的名称。可以是Port Forward,也可以称为映射等...这是必需的,以便入站流量直接进入您的程序。
如果您在本地局域网上尝试此操作(在计算机上禁用防火墙),则需要使用内部IP地址(10.0.0.x)连接笔记本电脑和其他计算机(您说的是同一IP) ,但在内部他们需要有不同的地址,否则他们不会工作。