c#通过Internet进行客户端/服务器同步通信

时间:2016-04-29 16:42:15

标签: c# sockets networking protocols wan

所以我创建了一个在局域网中工作的“简单聊天应用程序”,但是当我尝试离开局域网时,它无效。我一直在网上寻找解决方案并遇到很多东西,比如NAT遍历,端口转发等等......我发现其中没有一个有用。我的问题是:如何让我的应用程序在WAN上运行?据我所知,我想要的是两台PC通过互联网相互通信(一个是客户端,另一个是模拟服务器),那些PC隐藏在使用NAT的路由器后面。但我不知道如何使我的应用程序工作。

服务器

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.Net.Sockets;

namespace sukaServer
{
    public partial class Form1 : Form
    {
        Socket sock;
        Socket accept;
        public Form1()
        {
            InitializeComponent();
        }

        Socket socket()
        {
            return new Socket(AddressFamily.InterNetwork, SocketType.Stream,     ProtocolType.Tcp);
    }

    private void buttonListenServ_Click(object sender, EventArgs e)
    {
        sock = socket();
        sock.Bind(new IPEndPoint(0, 80));
        sock.Listen(0);

        new Thread(delegate ()
        {
            accept = sock.Accept();
            MessageBox.Show("CONNECTED!");
            sock.Close();

            while (true)
            {
                try
                {
                    byte[] buffer = new byte[255];
                    int rec = accept.Receive(buffer, 0, buffer.Length, 0);

                    if (rec <= 0)
                    {
                        throw new SocketException();
                    }

                    Array.Resize(ref buffer, rec);

                    Invoke((MethodInvoker)delegate
                    {
                        listBoxServer.Items.Add(Encoding.Default.GetString(buffer));
                    });
                }
                catch
                {
                    MessageBox.Show("DISCONNECTED!");
                    sock.Close();
                    break;
                }
            }
            Environment.Exit(0);
        }).Start();
    }

    private void buttonServerSend_Click(object sender, EventArgs e)
    {
        byte[] data = Encoding.Default.GetBytes(textBoxServerSend.Text);
        accept.Send(data, 0, data.Length, 0);
        textBoxServerSend.Clear();
    }
}
}

客户端:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace suka
{
    public partial class Form1 : Form
    {
        Socket sock;
        Socket socket()
        {
        return new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }
    public Form1()
    {
        InitializeComponent();
        sock = socket();
        FormClosing += new FormClosingEventHandler(Form1_FormClosing);
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        sock.Close();
    }

    private void buttonClientConnect_Click(object sender, EventArgs e)
    {
        try
        {
            sock.Connect(new IPEndPoint(IPAddress.Parse(textBoxClientConnect.Text), 80));
            new Thread(delegate ()
            {
                read();
            }).Start();
        }
        catch
        {
            MessageBox.Show("CANNOT CONNECT!");
        }
    }

    void read()
    {
        while (true)
        {
            try
            {
                byte[] buffer = new byte[255];
                int rec = sock.Receive(buffer, 0, buffer.Length, 0);

                if (rec <= 0)
                {
                    throw new SocketException();
                }

                Array.Resize(ref buffer, rec);

                Invoke((MethodInvoker)delegate
                {
                    listBoxClient.Items.Add(Encoding.Default.GetString(buffer));
                });
            }
            catch
            {
                MessageBox.Show("DISCONNECTED!");
                sock.Close();
                break;
            }
        }
        Environment.Exit(0);
    }


    private void buttonClientSend_Click(object sender, EventArgs e)
    {
        byte[] data = Encoding.Default.GetBytes(textBoxClientSend.Text);
        sock.Send(data, 0, data.Length, 0);
        textBoxClientSend.Clear();
    }
}
}

我知道第一眼看上去就像副本一样,但我看到的帖子都没有解决相同的问题,他们要么A和B要通过服务器进行通信,要么就是其他问题。我希望A和B聊天,其中A是服务器,B是客户端,反之亦然。我想要的第一件事就是让它能够在互联网上工作,之后我将解决异步问题。

修改 Lemme只是澄清了“不工作”的事情......它引发了一个例外,即捕获并通过(“无法连接!”)代码的一部分。

2 个答案:

答案 0 :(得分:0)

如果两台计算机都在NAT后面,则需要在至少一个节点上配置端口转发。许多家庭路由器可以通过使用uPnP协议动态执行此操作,而无需登录路由器。

答案 1 :(得分:-1)

我在我以前的公司用NamedPipes尝试过,它正在运行。