黑马程序员_第九篇:socket学习最终代码(服务端)
2011-12-03 14:33
183 查看
---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ----------------------
首先理清思路
服务端首先一个线程是用来接收连接请求的,他有一个while循环,用来不断接收请求,其中用一个socket
接收到请求后,为这个来连接的客户端创建一个线程,调用一个socket,用来和他通信
由于还会有客户端来连接,所以放在一个循环里,每循环一次,就创建一个线程,里面一个socket。
应为每次创建的线程和socket会覆盖上一个线程和socket,所以不能用全局变量,应该把每次的线程和socket存在dictionary里
---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ----------------------
首先理清思路
服务端首先一个线程是用来接收连接请求的,他有一个while循环,用来不断接收请求,其中用一个socket
接收到请求后,为这个来连接的客户端创建一个线程,调用一个socket,用来和他通信
由于还会有客户端来连接,所以放在一个循环里,每循环一次,就创建一个线程,里面一个socket。
应为每次创建的线程和socket会覆盖上一个线程和socket,所以不能用全局变量,应该把每次的线程和socket存在dictionary里
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.Sockets; using System.Net;//ip,ipaddress,ipEndPoint(ip和端口)类 using System.Threading; using System.IO; namespace MyChatRoomServer { public partial class FChatServer : Form { public FChatServer() { InitializeComponent(); TextBox.CheckForIllegalCrossThreadCalls = false; } Thread threadWatch = null; Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>(); Socket watchSocket = null; private void btnBeginListen_Click(object sender, EventArgs e) { //创建服务端负责监听的套接字,参数(连接方式ipv4,使用流的形式,协议用tcp协议传输数据) watchSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //获取文本框中的ip地址 IPAddress address = IPAddress.Parse(txtIp.Text.Trim()); //创建包含ip和port的网络节点对象 IPEndPoint endPoint = new IPEndPoint(address,int.Parse(txtPort.Text)); //将负责监听的套接字绑定到ip和port上 watchSocket.Bind(endPoint); //设置监听队列的长度 watchSocket.Listen(10); threadWatch = new Thread(WatchConnection); threadWatch.IsBackground = true; threadWatch.Start(); ShowMsg("服务器启动监听成功!"); } Dictionary<string, Socket> dict = new Dictionary<string, Socket>(); void WatchConnection() { while (true) { //设置套接字开始监听,并接返回一个新的套接字对象,用于和客户端连接,注意accept方法会阻断当前线程 Socket sokConnection = watchSocket.Accept(); lbOlineIp.Items.Add(sokConnection.RemoteEndPoint.ToString()); //向dictionary中添加 dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection); //设计一个线程负责运行每个连接客户端的socket Thread thr = new Thread(recMsg); thr.IsBackground = true; thr.Start(sokConnection); //把线程加入到字典里 dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr); ShowMsg("连接客户端成功!" + sokConnection.RemoteEndPoint.ToString()); } } //服务端负责监听客户端发送来数据的方法 void recMsg(object socketConnectionPara) { Socket socketClient = socketConnectionPara as Socket; while (true) { byte[] arrMsgRec = new byte[1024 * 1024 * 2]; int length = -1; try { length = socketClient.Receive(arrMsgRec); } catch (SocketException ex) { ShowMsg("异常:" + ex.Message); dict.Remove(socketClient.RemoteEndPoint.ToString()); dictThread.Remove(socketClient.RemoteEndPoint.ToString()); lbOlineIp.Items.Remove(socketClient.RemoteEndPoint.ToString()); break; } catch (Exception ex) { ShowMsg("异常:" + ex.Message); break; } if (arrMsgRec[0] == 0)//判断发送过来的一个数据是0则是文本 { string steMsgRce = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length-1); ShowMsg(steMsgRce); } else if (arrMsgRec[0] == 1)//如果是1则是文件 { SaveFileDialog sfd = new SaveFileDialog(); if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { string fileSavePath = sfd.FileName; using (FileStream fs = new FileStream(fileSavePath, FileMode.Create)) { fs.Write(arrMsgRec, 1, length - 1); ShowMsg("文件保存成功!" + fileSavePath); } } } } } void ShowMsg(string Msg) { txtMsg.AppendText(Msg + "\r\n"); } private void FChatServer_Load(object sender, EventArgs e) { } private void btnSend_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(lbOlineIp.Text)) { MessageBox.Show("请选择要发送信息的好友"); } else { string strMsg = txtSendMsg.Text.Trim(); //将要发送的字符串转换为utf8对应的字节数组 byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); //获得列表中选中的ip string strClientKey = lbOlineIp.Text; //通过key找到dictionary中的socket的send方法发送信息 try { dict[strClientKey].Send(arrMsg); } catch (SocketException ex) { ShowMsg("发送时异常:" + ex.Message); } catch (Exception ex) { ShowMsg("发送时异常:" + ex.Message); } //sokConnection.Send(arryMsg); ShowMsg("发送了数据:" + strMsg); } } private void lbOlineIp_SelectedIndexChanged(object sender, EventArgs e) { } private void btnSendAll_Click(object sender, EventArgs e) { string strMsg = txtSendMsg.Text.Trim(); //将要发送的字符串转换为utf8对应的字节数组 byte[] arryMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); foreach (Socket s in dict.Values) { s.Send(arryMsg); ShowMsg("群发成功"); } } } }
---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ----------------------
相关文章推荐
- 黑马程序员_第十篇:socket学习最终代码(客户端)
- 黑马程序员学习日记(9)--socket服务端与客户端连接(1)
- 黑马程序员学习日记(10)--socket服务端与客户端信息发送(2)
- 黑马程序员<.net学习---Socket 服务端与客户端的交互>
- 学习之路八:解决不能调试服务端代码的问题
- 黑马程序员——Socket的学习
- socket客户端与服务端代码(解决16进制输入流转换字符串操作)
- [置顶] C#中Socket服务端代码分享
- Windows下C++服务端和客户端Socket通信简单代码
- Windows 编程[6] - 学习窗体生成的过程六: 最终的代码!
- Socket编程服务端和客户端代码
- android 建立Socket长链接 服务端 - 客户端代码
- 黑马程序员——反射问题代码学习点
- Linux 下socket编程客户端与服务端代码
- Tensorflow学习:ResNet代码(详细剖析)-待补充,非最终版本
- C++ 简单Socket服务端代码实现
- 黑马程序员--C#Socket学习总结
- volatile的工作机制代码测试之socket学习笔记
- android 建立Socket长链接 服务端 - 客户端代码(+1)
- 用C++编写的SOCKET服务端与客户端代码实例