首先自己先扔个小例子吧0.0虽然写的不好....只是一个p2p的,使用的是TCP
首先是服务端的 class Program
    {
        int port = 4444;//端口号
        List<string> list=new List<string>();//用于存放已经登录上线的客户端IP
        static void Main(string[] args)
        {
            new Program().listen();
        }
        public void listen()//侦听客户端的端口
        {
            try
            {
                TcpListener listener = new TcpListener(port);
                while (true)//循环侦听
                {
                    listener.Start();//侦听开启
                    Console.WriteLine("服务端开始运行...");
                    TcpClient tcp = listener.AcceptTcpClient();
                    NetworkStream network = tcp.GetStream();
                    Console.WriteLine("连接建立成功!");
                    string s = tcp.Client.RemoteEndPoint.ToString();
                    s = s.Substring(0, s.IndexOf(':'));//获取远程连接客户端的IP地址
                    if (list.Count != 0)//防止记录相同的IP地址
                    {
                        for (int i = 0; i < list.Count; i++)
                        {
                            if (s == list[i])
                            {
                                list.Remove(list[i]);
                            }
                        }
                    }
                        list.Add(s);//将获取到的IP地址存放于list泛型结合中
                    if (list.Count != 0)//如果list集合里面有数据的话,那么说明有人在线,则将在线人的地址发送过去
                    {
                        StreamWriter sw = new StreamWriter(network);
                        foreach (string str in list)//循环list中的内容并将其传送到客户端
                        {
                            sw.WriteLine(str);
                        }
                        sw.Flush();
                        sw.Close();
                    }
                    network.Close();//关闭流
                    listener.Stop();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
然后下面是客户端的,这个页面只是读取上线用户的IP地址
 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        int port = 4444;
        string IP = "192.168.8.6";
        delegate void del(string s);//combobox1的回调委托
        delegate void del2();//用于清空combobox
        private void Form1_Load(object sender, EventArgs e)
        {
            Thread t1 = new Thread(mymehod);//开启一个线程连接服务端
            t1.IsBackground = true;
            t1.Start();
        }
        private void mymehod()//线程t1的委托方法
        {
            try
            {
                while (true)
                {
                    Thread.Sleep(1000);
                    comboBox1.Invoke(new del2(clear));
                    TcpClient tcp = new TcpClient(IP, port);
                    NetworkStream network2 = tcp.GetStream();                    StreamReader sr = new StreamReader(network2);//连接服务端后直接读取?
                    string s = sr.ReadLine();
                    string s2;
                    while (true)
                    {
                        if (s != null)
                        {
                            if (comboBox1.InvokeRequired)//combobox1委托回调
                            {
                                comboBox1.Invoke(new del(combobox1), s);
                            }
                        }
                        s2 = s;
                        s = sr.ReadLine();
                        if (s == s2)//
                        {
                            break;
                        }
                    }
                    network2.Close();
                    sr.Close();
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        private void combobox1(string s)//委托回调方法
        {
            comboBox1.Items.Add(s);
        }
        private void clear()//清空combobox
        {
            comboBox1.Items.Clear();
        }        private void button1_Click(object sender, EventArgs e)//开始聊天
        {
            if (comboBox1.Text.Trim() != null)
            {
                chatinfo c = new chatinfo(comboBox1.Text);
                c.Show();
                this.Hide();
            }
            else
            {
                MessageBox.Show("请选择要聊天的IP");
            }
        }
    }
下面这个是聊天的...  public partial class chatinfo : Form
    {
        string chatip;
        int chatport = 4445;
        public chatinfo()
        {
            InitializeComponent();
        }
        public chatinfo(string ip)//传入聊天IP
        {
            InitializeComponent();
            chatip = ip; 
        }        private void chatinfo_Load(object sender, EventArgs e)
        {
            Thread t = new Thread(mythread);
            t.IsBackground = true;
            t.Start();
            //Thread t2 = new Thread(format);
            //t2.IsBackground = true;
            //t2.Start();
        }
        private void mythread()//线程T的方法
        {
            chatserice c = new chatserice(chatport, listBox1);
            c.listen();
        }
        //private void format()//发送图片委托
        //{ 
        //}        private void button1_Click(object sender, EventArgs e)//发送
        {
            try
            {
                TcpClient tcp = new TcpClient(chatip, chatport);
                NetworkStream network = tcp.GetStream();
                StreamWriter sw = new StreamWriter(network);
                sw.WriteLine(textBox1.Text);
                sw.Flush();
                sw.Close();
                network.Close();
                listBox1.Items.Add( "      " + textBox1.Text + "      " + DateTime.Now.ToLocalTime());
                textBox1.Text = "";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }        private void button2_Click(object sender, EventArgs e)//发送图片
        {
            try
            {
                BinaryFormatter bf = new BinaryFormatter(); //序列化
                Bitmap bit = new System.Drawing.Bitmap(pictureBox1.Image);
                TcpClient tcpc = new TcpClient();
                NetworkStream n = tcpc.GetStream();
                bf.Serialize(n, bit);
                StreamWriter sw = new StreamWriter(n);
                sw.Flush();
                sw.Close();
                n.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        } 
    }我想问下那个NAT技术现在成熟没有,在实际开发的情况中到底用处怎样还有一般情况下由客户端主动去连接服务器的情况下,是补存在路由穿透的问题,是不是可以利用这种机制去开发...来的人都谈谈吧。分不是问题......

解决方案 »

  1.   

    NAT穿墙是一个非常复杂的过程,技术上已经很成熟了,不过真正的代码实现,是要很深的技术功底的
    从你的代码中,我看不到一点P2P的影子,这根本不是P2P,只是一个普通的聊天室服务器端而已,对P2P都缺乏最基本的常识,建议年轻人还是好好打好基础,不要想着一步登天!!
      

  2.   

    看见是TCP来实现P2P,把我吓了一大跳。(虽然理论上也能实现)p2p不是说 A发消息 最终 B能收到 就成为了P2P。 没这么简单。要p2p的话就要做到NAT穿透,这是个很繁琐的过程。 网上关于UDP P2P的例子C++代码也有几个,baidu都能搜索出来。 看懂C++之后实现一个C#版本的应该不成问题。http://www.pconline.com.cn/pcedu/soft/lan/kdwjr/0508/691532.html
      

  3.   

    楼主写的确实和NAT没有任何关系。
    udp的nat .net版本的已经有了。
    TCP版的好象还有同有见到(指.net版)
      

  4.   

    楼主应该买本TCPIP的书看看协议。
      

  5.   

    我这个小例子本来就没用到那个NAT...因为那个我还不会这两天一直在想0.0.....上面那个确实只是一个简单的局域网聊天....
      

  6.   

    你先不要想着怎么来做一些NAT,我建议你首先把你上面的例子全部吃透,然后用异步操作来实现以上的代码,基于P2P形式的开发,都是需要异步通讯的
      

  7.   

    大家说说这些通讯的原理吧,不管是p2p或者群聊天或者NAT,说说通讯原理吧...代码实现自己琢磨琢磨就好啦,关键是原理