---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------
服务端
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net; using System.Threading; using System.IO; namespace MyChatroomServer { public partial class MyChatroomServer : Form { public MyChatroomServer() { InitializeComponent(); TextBox.CheckForIllegalCrossThreadCalls = false; //关闭对文本框的跨线程操作 } Thread threadWatch = null;//负责监听客户端连接请求的线程 Socket SocketWatch = null;//负责监听的套接字 Socket sokConnectin = null;//负责通信的套接字 Thread threadRec = null; Socket sokRec = null; //保存服务器端所有负责和客户端通信的套接字 Dictionary<string, Socket> dic = new Dictionary<string, Socket>(); //保存服务器端所有负责调用通信套接字.Receive()方法的线程 Dictionary<string, Thread> dicThread = new Dictionary<string, Thread>(); private void btnListen_Click(object sender, EventArgs e) { //创建负责监听的套接字,参数(使用ip4寻址协议,使用流式连接,使用tcp协议) SocketWatch = 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.Trim())); //将负责监听的套接字绑定到唯一个IP和端口上 SocketWatch.Bind(endpoint); //设置监听队列的长度 SocketWatch.Listen(10); //创建负责监听的线程,并传入方法 threadWatch = new Thread(WatchConnecting); threadWatch.IsBackground = true;//设置为后台线程 threadWatch.Start();//开启线程 showMsg("服务器启动监听成功"); } void WatchConnecting() { while (true) { //开始监听客户端的请求,注意:accept方法会阻断当前线程 sokConnectin = SocketWatch.Accept();//一但监听到客户端的请求,就返回一个负责和该客户 //将与客户端通信的套接字对象sokConnectin添加到键值中,并以IP作为标识 dic.Add(sokConnectin.RemoteEndPoint.ToString(), sokConnectin); //向列表控件中添加一个客户端ip端口字符串,作为客户的唯一标示 lbOnline.Items.Add(sokConnectin.RemoteEndPoint.ToString()); //端通信的sokconnection threadRec = new Thread(receiveMsg); showMsg("客户端连接成功"); threadRec.SetApartmentState(ApartmentState.STA); threadRec.IsBackground = false; threadRec.Start(sokConnectin); dicThread.Add(sokConnectin.RemoteEndPoint.ToString(), threadRec); } } void receiveMsg(object sokConnectinPara) { Socket sokConnectin = sokConnectinPara as Socket; while (true) { //定义一个接收用的缓存(字节数组) byte[] arrMsgRec = new byte[1024 * 1024]; //将接收到的数据存入arrMsgRec数组 int length = -1; try { length = sokConnectin.Receive(arrMsgRec); } catch (SocketException ex) { showMsg("异常:" + ex.Message); dic.Remove(sokConnectin.RemoteEndPoint.ToString()); dicThread.Remove(sokConnectin.RemoteEndPoint.ToString()); lbOnline.Items.Remove(sokConnectin.RemoteEndPoint.ToString()); break; } catch (Exception ex) { showMsg("异常:" + ex.Message); break; } if (arrMsgRec[0] == 0)//判断发送过来的是文字还是文件 { string msg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length - 1); showMsg(msg); } else if (arrMsgRec[0] == 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 + " "); } private void btnSend_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(lbOnline.Text)) { showMsg("请选择发送对象"); } else { string msg = txtMsgSend.Text.Trim(); //将要发送的字符串转成UTF8对应的字节数组 byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(msg); string strClintKey = lbOnline.Text; try { dic[strClintKey].Send(arrMsg); } catch (SocketException ex) { showMsg("异常:" + ex.Message); } catch (Exception ex) { showMsg("异常:" + ex.Message); } // sokConnectin.Send(arrMsg); showMsg("发送了数据出去" + msg); } } private void btnSendAll_Click(object sender, EventArgs e) { string msg = txtMsgSend.Text.Trim(); //将要发送的字符串转成UTF8对应的字节数组 byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(msg); foreach (Socket s in dic.Values) s.Send(arrMsg); // sokConnectin.Send(arrMsg); showMsg("群发了:" + msg); } } }
客户端
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net; using System.Threading; using System.IO; namespace MyChatroomClint { public partial class MyChatroomClient : Form { public MyChatroomClient() { InitializeComponent(); TextBox.CheckForIllegalCrossThreadCalls = false; } Thread threadClinet = null;//客户端负责监听服务端线程的消息 Socket socketClient = null; private void btnconnect_Click(object sender, EventArgs e) { 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); //向指定的IP端口发送请求 socketClient.Connect(endpoint); //创建线程 threadClinet = new Thread(receiveMsg); threadClinet.IsBackground = true; threadClinet.Start(); } void receiveMsg() { while (true) { //定义一个接收用的缓存(字节数组) byte[] arrMsgRec = new byte[1024 * 1024]; //将接收到的数据存入arrMsgRec数组 int length=socketClient.Receive(arrMsgRec); string msg = System.Text.Encoding.UTF8.GetString(arrMsgRec,0,length); showMsg(msg); } } void showMsg(string msg) { txtMsg.AppendText(msg + " "); } private void btnSend_Click(object sender, EventArgs e) { string msg = txtMsgSend.Text.Trim(); byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(msg); byte[] arrMsgSend = new byte[arrMsg.Length + 1]; arrMsgSend[0] = 0; arrMsg.CopyTo(arrMsgSend,1); // Buffer.BlockCopy(arrMsg, 0, arrMsgSend, 1, arrMsg.Length ); socketClient.Send(arrMsgSend); showMsg("发送了数据出去" + msg); } //选择要发送的文件 private void btnChoseFile_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { txtFilePath.Text = ofd.FileName; } } //向服务器端发送文件 private void btnSendFile_Click(object sender, EventArgs e) { //用文件流打开用户选择的文件 using (FileStream fs = new FileStream(txtFilePath.Text, FileMode.Open)) { byte[] arrFile = new byte[1024 * 1024*2];//定义一个2M的缓存区 //将文件数据读到数组arrFile中,并获得真实长度Length int length = fs.Read(arrFile,0,arrFile .Length); byte[] arrFileSend = new byte[length + 1]; arrFileSend[0] = 1;//1代表发送的是文件数据 //将arrFile数组里的元素从第0个开始拷贝,拷贝到arrFileSend数组里,从第1个位置开始存放,一共拷贝length个数据 Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length); //arrFile.CopyTo(arrFileSend, 1);//另外一种方法,从第一个位置开始复制 socketClient.Send(arrFileSend);//发送了包含表示符的文件 showMsg("文件发送完毕"); } } } }
---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------