Socket编程(一):建立与客户端的连接并接受数据

我们这里利用Socket在模拟一个客户端与服务器通信,其实客户端与服务端通信就像人与人打电话一样,想要给一个人打电话,我们首先必须要有手机,必须知道对方的手机号码,这里Socket就好比一部手机,而短点就好比手机号,但是当你拨了电话,还需要对方接了以后才算是可以通信,下面我们来看一看代码:

首先写服务器端:

 

这里我们指定一个ip地址和端口号:然后开始对它进行监听;

        private void btnListen_Click(object sender, EventArgs e)
        {
            //ip地址
            IPAddress ip = IPAddress.Parse(this.txtServer.Text);
            //网络端口号
            IPEndPoint endpoint = new IPEndPoint(ip, int.Parse(txtPort.Text));

            //负责监听的Socket
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //绑定本地短点
            try
            {
                socket.Bind(endpoint);//这里绑定一个端点
                socket.Listen(10);
                SetText("开始监听");
                btnListen.Enabled = false;
            }
            catch(Exception ex)
            {
                btnListen.Enabled = true;
                SetText(ex.Message);
                return;
            }

            //创建线程,用来执行socket监听客户端,为什么要创建一个线程呢,因为这里我想多找一个人来干活,让它替主线程分担点任务
            Thread th = new Thread(Accept);
            th.IsBackground = true;//设置为后台线程
            th.Start(socket);
        }

        Dictionary<string, Socket> dic = new Dictionary<string, Socket>();

        int n = 10;//创建10个客户端的连接
        //接受客户端的连接,避免主线程陷入死循环
        void Accept(object o)
        {
            while (n>0)
            {
                n--;
                //监听用的Socket
                Socket socket = o as Socket;

                //当有客户端连接成功后,创建通信用的Socket
                Socket connSocket = socket.Accept();

                //获取客户端ip和端口号
                string ip = connSocket.RemoteEndPoint.ToString();
                //把客用户端ip和通信用的Socket存放到字典中
                dic.Add(ip, connSocket);
                cmbIP.Items.Add(ip);

                //提示连接成功
                SetText( ip+ "连接成功!");
                //服务端接受客户端发来的信息
                Thread th = new Thread(ReciveMsg);
                th.Start(connSocket);
            }

            
        }

那么如果客户端接了电话,那么我们要接收客户端的发来的信息

 1   void ReciveMsg(object o)
 2         {
 3             Socket connSocket = o as Socket;//我们这个Socket是我们上面创建的用来连接通信的,与监听的Scoket区别开
 4             byte[] buffer = new byte[1024 * 1024 * 5];//设置最多接收5兆的信息
 5             while (true)//这里我们循环接收客户端的信息,客户端可以一直发信息,我们创建线程的好处就在这里,因为主线程一旦陷入死循环,那么这个程序就卡了
 6             {
 7                 int count = connSocket.Receive(buffer);//把接收到的信息放在buffer中
 8                 if (count > 0)
 9                 {
10                     string s = Encoding.UTF8.GetString(buffer, 0, count);
11                     SetText(connSocket.RemoteEndPoint.ToString() + ":" + s);
12                 }
13                 else
14                 {
15                     SetText(connSocket.RemoteEndPoint.ToString()+"断开连接");
16                     connSocket.Close();
17                     break;
18                 }
19             }
20         }

 

 /// <summary>
        /// 发送消息 开头标记为0
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            //判断下拉框是否有选项
            if (cmbIP.SelectedIndex >= 0)
            {
                string key = cmbIP.Text;
                byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text);
                List<byte> list = new List<byte>();
                list.Add(0);
                list.AddRange(buffer);
                dic[key].Send(list.ToArray());
            }
            else
            {
                MessageBox.Show("请选择客户端用户!");
            }
        }

 

 1 /// <summary>
 2         /// 发送文件
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         private void button2_Click(object sender, EventArgs e)
 7         {
 8             if (!string.IsNullOrEmpty(txtFilePath.Text))
 9             {
10                 if (cmbIP.SelectedIndex >= 0)
11                 {
12                     string key = cmbIP.Text;
13                     FileStream fs = new FileStream(txtFilePath.Text, FileMode.Open);
14                     byte[] buffer=new  byte[fs.Length];
15                     fs.Read(buffer, 0, buffer.Length);
16                      
17                     //文件 标记开头为1
18                     List<byte> list = new List<byte>();
19                     list.Add(1);
20                     list.AddRange(buffer);
21 
22                     dic[key].Send(list.ToArray());
23                 }
24                 else
25                 {
26                     MessageBox.Show("请选择客户端用户!");
27                 }
28             }
29             else
30             {
31                 MessageBox.Show("请选择文件!");
32             }
33         }


先把服务器端的写一下。

 

posted @ 2013-06-26 11:30  YoMe  阅读(9881)  评论(1编辑  收藏  举报