Fork me on GitHub

C#网络编程简单实现通信小例子-2

1、主界面                                                         

2、源代码                                                        

Client

public partial class FormClient : Form
    {
        //声明一个Socket
        public Socket newClient;
        //判断是否连接成功
        public bool isConnected;
        //定义一个线程
        public Thread myThread;
        //定义一个委托
        public delegate void MyInvoke(string str);
        public FormClient()
        {
            InitializeComponent();
        }

        private void Connection()
        {
            //IPAddress ip=null;
            //int port=888;
            byte[]data=new byte[1024];
            //创建一个新的Socket
            newClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //获取IP地址
            #region GetIP
            //if (txtIP.Text == string.Empty)
            //{
            //    MessageBox.Show("远程IP不能为空");
            //}
            //else
            //{
            //    string pattrn = @"((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))))";
            //    if (System.Text.RegularExpressions.Regex.IsMatch(txtIP.Text.Trim(), pattrn))
            //    {
            //        ip = IPAddress.Parse(txtIP.Text.Trim());
            //    }
            //    else
            //    {
            //        MessageBox.Show("IP地址格式不正确!");
            //    }
            //} 
            
            #endregion
            //获取端口号
            #region GetPort
            //if (System.Text.RegularExpressions.Regex.IsMatch(@"^[-]?\d+[.]?\d*$", txtPort.Text.Trim()))
            //{
            //    port = Convert.ToInt32(txtPort.Text.Trim());
            //}
            //else
            //{
            //    MessageBox.Show("端口号格式不正确");
            //} 
            #endregion
            //封装网络端点
            IPEndPoint ie = new IPEndPoint(IPAddress.Parse(txtIP.Text.Trim()),Convert.ToInt32(txtPort.Text.Trim()));
            #region Connection
            try
            {
                //建立与远程主机之间的连接
                newClient.Connect(ie);
                //设置连接服务器控件的属性
               // btnConnection.Enabled = false;
                //设置连接状况
                btnConnection.Text = "停止连接";
                //isConnected = true;
            }
            catch (SocketException ex)
            {
                MessageBox.Show("连接服务器失败" + ex.Message);
                return;
            } 
            #endregion
            //启动当前线程用于接收消息
            ThreadStart myThreadDelegate = new ThreadStart(ReceiveMessage);
            myThread = new Thread(myThreadDelegate);
            myThread.Start();
        }
        /// <summary>
        /// 接收消息
        /// </summary>
        public void ReceiveMessage()
        {
            while (true)
            { 
                //定义字节数组大小
                byte[]data=new byte[1024];
                //获取数组长度
                int recv = newClient.Receive(data);
                //接收数据
                string strData = Encoding.UTF8.GetString(data, 0, recv);
                //显示信息
                ShowMessage(newClient.RemoteEndPoint.ToString()+":"+strData+"\r\n");
            }
        }
        /// <summary>
        /// 显示消息
        /// </summary>
        /// <param name="msg">接收的消息,可能来自Client/也可能来自Server</param>
        public void ShowMessage(string msg)
        {
            //如果是在创建该控件以外的线程调用该控件
            if (lbMessage.InvokeRequired)
            {
                MyInvoke myInvoke = new MyInvoke(ShowMessage);
                //lbMessage.Invoke(myInvoke, new object[] { msg });
                lbMessage.Invoke(myInvoke,new object[]{"远程主机:"+msg});
            }
            else
            {
                lbMessage.Items.Add(msg);
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (txtSendMessage.Text == null)
            {
                txtSendMessage.Text = "发送消息不能为空";
                //停留1秒消失
            }
            else
            {
                //获取发送数据长度
                int myMessLength = txtSendMessage.Text.Length;
                //将数据转换为字节数组
                byte[] data = new byte[myMessLength];
                data = Encoding.UTF8.GetBytes(txtSendMessage.Text);
                //发送数据
                int i = newClient.Send(data);
                //将数据显示在Client
                ShowMessage("我说:" + txtSendMessage.Text + "\r\n");
            }
        }

        private void btnConnection_Click(object sender, EventArgs e)
        {
            if (btnConnection.Text == "连接服务")
            {
                Connection();
            }
            else
            {
                newClient.Close();
            }
        }

        private void FormClient_Load( object sender, EventArgs e )
        {

        }
        
    }

Server

 

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public Thread myThread;//声明一个线程实例
        public Socket newSocket;//声明一个Socket实例
        public Socket serverSocket;//声明服务端Socket实例
        public Socket clientSocket;//声明客户端Socket
        public delegate void MyInvoke(string str);//声明一个委托
        public IPEndPoint localEP;//声明本地网络端点
        public EndPoint remote;//声明网络地址
        public int localPort;//声明本地端口号
        public Boolean isListening;//声明服务端是否监听
        public Hashtable _sessionTable;//用于记录用户信息
        public bool btnState=true;
        //设置服务端监听的端口号属性
        public int SetPort
        {
            get { return localPort; }
            set { localPort = value; }
        }
        //设置监听
        public void Listening()
        {
            SetPort = int.Parse(txtPort.Text.Trim());//设置端口号
            newSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化Socket实例
            newSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);//允许Socket被绑定在已使用的地址上
            localEP = new IPEndPoint(IPAddress.Any, SetPort);//初始化网络端点信息
            try
            {
                _sessionTable = new Hashtable( 50 );
                newSocket.Bind(localEP);//绑定端口
                newSocket.Listen(10);//开始监听
                newSocket.BeginAccept(new AsyncCallback(OnConnectRequest),newSocket);//开始异步接受连接
            }
            catch(Exception ex)
            {
                ShowMessage(ex.ToString());
            }
            
        }
        private void btnStartServer_Click(object sender, EventArgs e)
        {
            ThreadStart myThreadDelegate = new ThreadStart(Listening);//新建一个线程用于委托
            myThread = new Thread(myThreadDelegate);
            if (btnState)
            {
                myThread.Start();
                stateBar.Text = "服务已经启动,等待客户端连接";
                btnState = false;
                btnStartServer.Text = "停止服务";
            }
            else
            {
                myThread.Interrupt();
                myThread.Abort();
                btnState = true;
                btnStartServer.Text = "开始服务";
                stateBar.Text = "服务已停止";
            }
        }
        //显示信息
        public void ShowMessage(string msg)
        {
            if (rtbMessage.InvokeRequired)
            {
                MyInvoke myInvoke = new MyInvoke(ShowMessage);
                rtbMessage.Invoke(myInvoke, new object[] { msg });
            }
            else
            {
                rtbMessage.AppendText(msg);
            }
        }
        public void OnConnectRequest(IAsyncResult ar)
        {
            serverSocket = (Socket)ar.AsyncState;
            clientSocket = serverSocket.EndAccept(ar);//异步接收连接
            string welcomeStr = "欢迎登陆到服务器";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(welcomeStr);
            remote = clientSocket.RemoteEndPoint;//获取远程终点信息
            ShowMessage(remote.ToString()+" 连接成功 "+DateTime.Now.ToString()+"\r\n");
            clientSocket.Send(data,data.Length,0);
            UserListOperate(clientSocket.RemoteEndPoint.ToString());
            _sessionTable.Add(clientSocket.RemoteEndPoint,null);//将连接成功的客户端实例添加到哈希表中
            serverSocket.BeginAccept(new AsyncCallback(OnConnectRequest), serverSocket);//等待新的客户端连接
            //接收数据
            ReceiveMessage();
        }
        //接收数据
        public void ReceiveMessage ()
        {
            while (true)
            { 
                byte[]data=new byte[1024];
                int recv = clientSocket.Receive( data );
                string message = Encoding.UTF8.GetString(data,0,recv);
                ShowMessage(clientSocket.RemoteEndPoint.ToString()+":"+message+"\r\n");
            }
        }
        //添加用户列表
        public void UserListOperate(string msg)
        {
            //在线程里以安全的方式调用控件
            if (lbUserList.InvokeRequired)
            {
                MyInvoke myInvoke = new MyInvoke(UserListOperate);
                lblUserList.Invoke(myInvoke, new object[] { msg });
            }
            else
            {
                lbUserList.Items.Add(msg);
            }
        }
        //删除用户列表
        public void UserListOperateRemove(string msg)
        {
            if (lbUserList.InvokeRequired)
            {
                MyInvoke myInvoke = new MyInvoke(UserListOperateRemove);
                lbUserList.Invoke(myInvoke, new object[] { msg });
            }
            else
            {
                lbUserList.Items.Remove(msg);
            }
        }
        //发送广播
        public void BroadCast()
        {
            string strMessage = txtMessage.Text;
            Byte[] data = Encoding.UTF8.GetBytes(strMessage);
            foreach (DictionaryEntry item in _sessionTable)
            {
                EndPoint temp = (EndPoint)item.Key;
                clientSocket.SendTo(data, temp);
                ShowMessage("我:"+strMessage+"\r\n");
            }
            txtMessage.Text = "";
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            //获取本机IP
            IPAddress[] ip = Dns.GetHostByName( Dns.GetHostName() ).AddressList;
            lblIP.Text+=ip[0].ToString();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //窗体关闭时判断线程是否为空
            if (myThread != null)
            {
                myThread.Abort();
            }
            throw new Exception();
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            BroadCast();
        }
    }

如有不当之处,烦请指教。

 

 

 

 

posted @ 2013-09-30 21:59  种花生的读书人  阅读(2583)  评论(7编辑  收藏  举报

该博客仅作为记录笔记,转载随意