.NET之Socket编程
.NET下Socket编程,可以实现发送文件和文本,部分代码如下:
服务器端程序:
Thread threadWatch=null;//负责监听客户端连接请求的线程 Socket watchSocket=null;//服务器端负责监听的套接字 private void btnBeginListen_Click(object sender,EventArgs e)//启动服务 { //创建负责监听的套接字(使用IP4协议,使用流式连接,使用Tcp协议传输数据) watchSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); //获得文本框的IP地址 IPAddress address = IPAddress.Parse(txtIP.Text.Trim()); //创建端口 IPEndPoint endpoint = new IPEndPoint(address,int.Parse(txtPort.Text.Trim())); //绑定端口 watchSocket.Bind(endpoint); //最多同时监听10个 watchSocket.Listen(10); //创建负责监听的线程 threadWatch = new Thread(WatchConnecting); threadWatch.IsBackgrount = true;//前台线程和后台线程。这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。 threadWatch.Start(); ShowMsg("服务器启动监听成功!"); } //保存了服务器端所有负责和客户端通信的套接字 Dictionary<string,Socket> dict = new Dictionary<string,Socket>(); void WatchConnecting() { while(true)//持续不断的监听客户端的连接请求 { //创建负责通信的套接字 Accept方法是会阻塞线程的 Socket SokConnection = watchSocket.Accept(); //将监听到的客户端的远程终结点添加到ListBox控件中 lbOnLint.Items.Add(SokConnection.RemoteEndPoint.ToString()); //将客户端的远程终结点和通信套接字以键值对的方式添加到dict中 dict.Add(SokConnection.RemoteEndPoint.Tostring(),SokConnection); //负责接收的线程 Thread thr = new Thread(RecMsg); thr.IsBackground = true; thr.Start(SokConnection); ShowMsg("客户端连接成功!"+SokConnection.RemoteEndPoint.ToString()); } } //服务器监听客户端发来的消息 void RecMsg(object socketClientpara) { Socket soketClient = socketClientpara as Socket; while(true) { byte[] arrMsgRec = new byte[1024*1024*2];//2M int length = -1; try { length = socketClient.Receive(arrMsgRec); } catch(SocketException ex) { ShowMsg("异常:"+ex.Message); dict.Remove(socketClient.RemoteEndPoint.ToString()); lbOnLine.Items.Remove(soketClient.ReomteEndPoint.ToString()); return; } catch(Exception ex) { ShowMsg("异常:"+ex.Message); return; } if(arrMsgRec[0] == 0)//0代表文本文字数据 { string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec,1,length-1); ShowMsg("收到:"+strMsgRec); } 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 btnSend_Click(object sender,EventArgs e) { if(string.IsNullOrEmpty(lbOnLine.Text)) { MessageBox.Show("请选择要发送的好友"); } else { string strMsg = txtMsgSend.Text.Trim(); byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); string strClientKey = lbOnLine.Text; try { dict[StrClientKey].Send(arrMsg); ShowMsg("发送:",strMsg); } catch(SocketException ex) { ShowMsg("异常:"+ex.Message); } catch(Exception ex) { ShowMsg("异常:"+ex.Message); } } } //群发 private void btnSendAll_Click(object sender,EventArgs e) { string strMsg = txtMsgSend.Text.Trim(); byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); foreach(Socket s in dict.Values) { s.Send(arrMsg); } ShowMsg("群发完毕~"); } private string getIPAddress() { IPAddress addr; addr = new IPAddress(Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].Address); return addr.ToString(); } private void Form1_Load(object sender,EventArgs e) { txtIP.Text = getIPAddress(); }
客户端程序:
Thread threadClient = null;//客户端负责接收服务器发来消息的线程 Socket socketClient = null;//客户端负责通讯的套接字 private void btnConnect_Click(object sender,EventArgs) { IPAddress address = IPAddress.Parse(txtIP.Text.Trim());//服务器端IP IPEndPoint endpoint = new IPEndPoint(address,int.Parse(txtPort.Text.Trim())); socketClient = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); socketClient.Connect(endpoint); threadCLient = new Thread(RecMsg); threadClient.IsBackground = true; threadClient.Start(); } //接收服务器发来的消息 void RecMsg() { while(true) { byte[] arrMsgRec = new byte[1024*1024*2];//2M int length = socketClient.Receive(arrMsgRec); string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec,0,length); ShowMsg("收到:"+strMsgRec); } } void ShowMsg(string msg) { txtMsg.AppendText(msg+"\r\n"); } //向服务器发送文本消息 private void btnSend_Click(object sender,EventArgs e) { string strMsg = txtMsgSend.Text.Trim(); byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); byte[] arrMsgSend = new byte[arrMsg.Length + 1]; arrMsgSend[0] = 0;//0代表文字 Buffer.BlockCopy(arrMsg,0,arrMsgSend,1,arrMsg.Length); socketClient.Send(arrmsgSend); ShowMsg("发送:"+strMsg); } //选择文件 private void btnChooseFile_Click(object sender,EventArgs e) { OpenFIleDialog ofd = new OpenFileDialog(); if(ofd.ShowDialog()==System.Windows.Forms.DialogResult.OK) { txtCHooseFIle.Text = ofd.FileName; } } //发送文件 private void btnSendFile_Click(object sender,EventArgs e) { using(FileStream fs = new FileStream(txtChooseFile.Text,FileMode.Open)) { byte[] arrFile = new byte[1024*1024*2]; int length = fs.Read(arrFile,0,arrFile.Length); byte[] arrFileSend = new byte[length + 1]; arrFileSend[0] = 1; Buffer.BlockCopy(arrFile,0,arrFileSend,1,length); socketClient.Send(arrFileSend); } }