博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网络聊天室
阅读量:6086 次
发布时间:2019-06-20

本文共 9322 字,大约阅读时间需要 31 分钟。

---------------------- 、、期待与您交流! ----------------------

服务端

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
dic = new Dictionary
(); //保存服务器端所有负责调用通信套接字.Receive()方法的线程 Dictionary
dicThread = new Dictionary
(); 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 + "\r\n"); } 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 + "\r\n");        }        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("文件发送完毕");                            }        }    }}

 

 

---------------------- 、、期待与您交流! ----------------------

转载于:https://www.cnblogs.com/qwsdxz/p/3171553.html

你可能感兴趣的文章
cad图纸转换完成的pdf格式模糊应该如何操作?
查看>>
Struts2与Struts1区别
查看>>
网站内容禁止复制解决办法
查看>>
Qt多线程
查看>>
我的友情链接
查看>>
想说一点东西。。。。
查看>>
css知多少(8)——float上篇
查看>>
NLB网路负载均衡管理器详解
查看>>
水平添加滚动条
查看>>
PHP中”单例模式“实例讲解
查看>>
VS2008查看dll导出函数
查看>>
VM EBS R12迁移,启动APTier . AutoConfig错误
查看>>
atitit.细节决定成败的适合情形与缺点
查看>>
Mysql利用binlog恢复数据
查看>>
我的友情链接
查看>>
用yum安装mariadb
查看>>
一点IT"边缘化"的人的思考
查看>>
WPF 降低.net framework到4.0
查看>>
搭建一个通用的脚手架
查看>>
开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
查看>>