• 网络聊天室


    ---------------------- 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培训、期待与您交流! ----------------------

  • 相关阅读:
    .NET Core 1.0正式发布
    【Azure Active Directory】单一登录 (SAML 协议)
    js原型链prototype与__proto__以及new表达式
    Claims Based Authentication and Token Based Authentication和WIF
    try-catch-finally对返回值的影响
    基于任务的异步编程模式,Task-based Asynchronous Pattern
    Session.Abandon-Session.Clear-Session.RemoveAll
    Html.Partial方法和Html.RenderPartial方法
    dynamic和nullable一起使用时的注意
    C#获取文件的Content-Type(MIME Type)的方法
  • 原文地址:https://www.cnblogs.com/qwsdxz/p/3171553.html
Copyright © 2020-2023  润新知