套接字似乎无法在两台计算机上运行

时间:2015-04-03 11:55:27

标签: sockets

我正面临着一个奇怪的问题,我写了一个简单的聊天应用程序,当我在一台机器上启动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个星期的时间打破了我的头......请有人帮忙...... :(

1 个答案:

答案 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) ,但在内部他们需要有不同的地址,否则他们不会工作。