WEB开发网
开发学院软件开发C语言 Udp打洞简单描述 阅读

Udp打洞简单描述

 2009-03-18 08:21:12 来源:WEB开发网   
核心提示: 和Port,这样2个客户端才算是真正的连通了,Udp打洞简单描述(2),这也解释了你的QQ好友隐身问什么你发送消息要等一段时间才能发送成功的原因所在,当然这是一种比较简单的处理方式,路由会自动跟你的电脑映射一个(除非你要监听一个端口),这里不要错误理解为服务器端口,应该是客户端监听消息的端

和Port,这样2个客户端才算是真正的连通了,这也解释了你的QQ好友隐身问什么你发送消息要等一段时间才能发送成

功的原因所在。当然这是一种比较简单的处理方式,还有一些更复杂点的,技术有限还没去研究过,但这是最基本的原理。

下面是我写的一些示例代码:(聊天没做,不过用户信息都获取到了,做起来很简单了)

客户端,界面自己拖拖就是了,就几个按钮、文本框加个显示所有登陆用户信息的listbox。

Client

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;
using System.Net;
using System.Net.Sockets;
using lib;
using System.Threading;

namespace Client
{
    public partial class FrmClient : Form
    {

        private IPEndPoint hostPoint;//服务器主机地址
        private IPEndPoint remotePoint;//目标主机地址
        private List<UserInfo> userInfoList;//保存所有登陆用户信息
        private Thread listenThread;//监听线程
        private UdpClient udpClient;

        public FrmClient()
        {
            InitializeComponent();
            userInfoList = new List<UserInfo>();
            listenThread = new Thread(new ThreadStart(Run));
        }

        /**//// <summary>
        /// 登陆按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLogin_Click(object sender, EventArgs e)
        {
            string serverIp = this.txtIP.Text;
            int Port = int.Parse(this.txtPort.Text);
            //不需要指定端口,路由会自动跟你的电脑映射一个(除非你要监听一个端口),这里不要错误理解为服务器端口,应该是客户端监听消息的端口
            udpClient = new UdpClient();
            remotePoint = new IPEndPoint(IPAddress.Any, 0);//提供任何端口和IP,这里不需要指定
            hostPoint = new IPEndPoint(IPAddress.Parse(serverIp), Port);//实例化主机地址
            LoginServer(this.txtUserName.Text);//由于udpClient还没有连接到服务器,所以要先登陆然后在监听
            this.btnLogin.Enabled = false;
            listenThread.Start();
        }

        /**//// <summary>
        /// 发送消息按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSend_Click(object sender, EventArgs e)
        {

        }

        /**//// <summary>
        /// 登陆服务器
        /// </summary>
        /// <param name="userName">用户名</param>
        private void LoginServer(string userName)
        {
            UserInfo userInfo = new UserInfo();
            userInfo.UserName = userName;
            byte[] buffer = SerializeHelper.Serialize(userInfo);
            udpClient.Send(buffer, buffer.Length, hostPoint);
            buffer = udpClient.Receive(ref remotePoint);
            UserList userList = (UserList)SerializeHelper.Deserialize(buffer);
            this.userInfoList = userList.userInfoList;
            foreach (UserInfo user in userInfoList)
            {
                this.lstUserInfo.Items.Add(user.UserName + ":" + user.Address.ToString());
            }
        }

        /**//// <summary>
        /// 监听线程
        /// </summary>
        private void Run()
        {
            byte[] buffer;
            while (true)
            {
                buffer = udpClient.Receive(ref remotePoint);
                try
                {
                    object msgObj = SerializeHelper.Deserialize(buffer);
                    Type msgType = msgObj.GetType();
                    if (msgType == typeof(UserList))
                    {
                        UserList userList = (UserList)msgObj;
                        this.userInfoList = userList.userInfoList;
                        this.lstUserInfo.BeginInvoke(new System.EventHandler(ClearUI), this.userInfoList);
                    }
                    Thread.Sleep(50);
                }
                catch
                { }
            }
        }

        /**//// <summary>
        /// 获取在线用户列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGetUserInfo_Click(object sender, EventArgs e)
        {
            GetUserList getUserList = new GetUserList();
            byte[] buffer = SerializeHelper.Serialize(getUserList);
            udpClient.Send(buffer, buffer.Length, hostPoint);
        }

        /**//// <summary>
        /// 跨线程访问控件
        /// </summary>
        /// <param name="o"></param>
        /// <param name="e"></param>
        private void ClearUI(object o, System.EventArgs e)
        {
            this.lstUserInfo.Items.Clear();
            this.lstUserInfo.Items.Add(((UserInfo)o).UserName + ":" + ((UserInfo)o).Address.ToString());
        }

        /**//// <summary>
        /// 窗体关闭事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmClient_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                if (this.listenThread.ThreadState == ThreadState.Running)
                {
                    this.listenThread.Abort();
                }
                udpClient.Close();
            }
            catch
            { }
        }

    }
}

上一页  1 2 3 4  下一页

Tags:Udp 简单 描述

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接