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 }
先把服务器端的写一下。