在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例桌面应用界面/GUI → 服务器和客户端(TCP发送消息、发送文件)

服务器和客户端(TCP发送消息、发送文件)

桌面应用界面/GUI

下载此实例
  • 开发语言:C#
  • 实例大小:3.65M
  • 下载次数:85
  • 浏览次数:484
  • 发布时间:2020-09-17
  • 实例类别:桌面应用界面/GUI
  • 发 布 人:wangf51
  • 文件格式:.zip
  • 所需积分:3
 相关标签: 客户端 服务器 服务

实例介绍

【实例简介】提供了服务器和客户端连接、通信和文件传输

【实例截图】

from clipboard


from clipboard

【核心代码】

 public partial class frm_server : Form
    {
        public frm_server()
        {
            InitializeComponent();
            TextBox.CheckForIllegalCrossThreadCalls = false;
        }

        Thread threadWatch = null; // 负责监听客户端连接请求的 线程;
        Socket socketWatch = null;

        Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
        Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();

        private void btnBeginListen_Click(object sender, EventArgs e)
        {
            // 创建负责监听的套接字,注意其中的参数;
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // 获得文本框中的IP对象;
            IPAddress address = IPAddress.Parse(txtIp.Text.Trim());
            // 创建包含ip和端口号的网络节点对象;
            IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));
            try
            {
                // 将负责监听的套接字绑定到唯一的ip和端口上;
                socketWatch.Bind(endPoint);
            }
            catch (SocketException se)
            {
                MessageBox.Show("异常:" se.Message);
                return;
            }
            socketWatch.Listen(10);
            // 创建负责监听的线程;
            threadWatch = new Thread(WatchConnecting);
            threadWatch.IsBackground = true;
            threadWatch.Start();
            ShowMsg("服务器启动监听成功!");
            //}
        }

        /// <summary>
        /// 监听客户端请求的方法;
        /// </summary>
        void WatchConnecting()
        {
            while (true)  // 持续不断的监听客户端的连接请求;
            {
                // 开始监听客户端连接请求,Accept方法会阻断当前的线程;
                Socket sokConnection = socketWatch.Accept(); // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字;
                // 想列表控件中添加客户端的IP信息;
                lbOnline.Items.Add(sokConnection.RemoteEndPoint.ToString());
                // 将与客户端连接的 套接字 对象添加到集合中;
                dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection);
                ShowMsg("客户端连接成功!");
                Thread thr = new Thread(RecMsg);
                thr.IsBackground = true;
                thr.Start(sokConnection);
                dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr);  //  将新建的线程 添加 到线程的集合中去。
            }
        }

        void RecMsg(object sokConnectionparn)
        {
                Socket sokClient = sokConnectionparn as Socket;
                while (true)
                {
                    // 定义一个2M的缓存区;
                    byte[] arrMsgRec = new byte[1024 * 1024 * 2];
                    // 将接受到的数据存入到输入  arrMsgRec中;
                    int length = -1;
                    try
                    {
                        length = sokClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
                    }
                    catch (SocketException se)
                    {
                        ShowMsg("异常:" se.Message);
                        // 从 通信套接字 集合中删除被中断连接的通信套接字;
                        dict.Remove(sokClient.RemoteEndPoint.ToString());
                        // 从通信线程集合中删除被中断连接的通信线程对象;
                        dictThread.Remove(sokClient.RemoteEndPoint.ToString());
                        // 从列表中移除被中断的连接IP
                        lbOnline.Items.Remove(sokClient.RemoteEndPoint.ToString());
                        break;
                    }
                    catch (Exception e)
                    {
                        ShowMsg("异常:" e.Message);
                        // 从 通信套接字 集合中删除被中断连接的通信套接字;
                        dict.Remove(sokClient.RemoteEndPoint.ToString());
                        // 从通信线程集合中删除被中断连接的通信线程对象;
                        dictThread.Remove(sokClient.RemoteEndPoint.ToString());
                        // 从列表中移除被中断的连接IP
                        lbOnline.Items.Remove(sokClient.RemoteEndPoint.ToString());
                        break;
                    }
                    if (arrMsgRec[0] == 0)  // 表示接收到的是数据;
                    {
                        string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec,1, length-1);// 将接受到的字节数据转化成字符串;
                        ShowMsg(strMsg);
                    }
                    if (arrMsgRec[0] == 1) // 表示接收到的是文件;
                    {
                            SaveFileDialog sfd = new SaveFileDialog();
                           
                            if (sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                            {// 在上边的 sfd.ShowDialog() 的括号里边一定要加上 this 否则就不会弹出 另存为 的对话框,而弹出的是本类的其他窗口,,这个一定要注意!!!【解释:加了this的sfd.ShowDialog(this),“另存为”窗口的指针才能被SaveFileDialog的对象调用,若不加thisSaveFileDialog 的对象调用的是本类的其他窗口了,当然不弹出“另存为”窗口。】
                               
                                string fileSavePath = sfd.FileName;// 获得文件保存的路径;
                                // 创建文件流,然后根据路径创建文件;
                                using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
                                {
                                    fs.Write(arrMsgRec, 1, length - 1);
                                    ShowMsg("文件保存成功:" fileSavePath);
                                }
                            }
                        }
                }     
        }

        void ShowMsg(string str)
        {
            txtMsg.AppendText(str "\r\n");
        }

        // 发送消息
        private void btnSend_Click(object sender, EventArgs e)
        {
            string strMsg = "服务器" "\r\n" "   -->" txtMsgSend.Text.Trim() "\r\n";
            byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;
            byte[] arrSendMsg=new byte[arrMsg.Length 1];
            arrSendMsg[0] = 0; // 表示发送的是消息数据
            Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
            string strKey = "";
            strKey = lbOnline.Text.Trim();
            if (string.IsNullOrEmpty(strKey))   // 判断是不是选择了发送的对象;
            {
                MessageBox.Show("请选择你要发送的好友!!!");
            }
            else
            {
                dict[strKey].Send(arrSendMsg);// 解决了 sokConnection是局部变量,不能再本函数中引用的问题;
                ShowMsg(strMsg);
                txtMsgSend.Clear();
            }
        }

        /// <summary>
        /// 群发消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e">消息</param>
        private void btnSendToAll_Click(object sender, EventArgs e)
        {
            string strMsg = "服务器" "\r\n" "   -->" txtMsgSend.Text.Trim() "\r\n";
            byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;
            foreach (Socket s in dict.Values)
            {
                s.Send(arrMsg);
            }
            ShowMsg(strMsg);
            txtMsgSend.Clear();
            ShowMsg(" 群发完毕~~~");
        }

        // 选择要发送的文件
        private void btnSelectFile_Click_1(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = "D:\\";
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtSelectFile.Text = ofd.FileName;
            }
        }

        // 文件的发送
        private void btnSendFile_Click_1(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtSelectFile.Text))
            {
                MessageBox.Show("请选择你要发送的文件!!!");
            }
            else
            {
                // 用文件流打开用户要发送的文件;
                using (FileStream fs = new FileStream(txtSelectFile.Text, FileMode.Open))
                {
                    string fileName=System.IO.Path.GetFileName(txtSelectFile.Text);
                    string fileExtension=System.IO.Path.GetExtension(txtSelectFile.Text);
                    string strMsg = "我给你发送的文件为: " fileName fileExtension "\r\n";
                    byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;
                    byte[] arrSendMsg = new byte[arrMsg.Length 1];
                    arrSendMsg[0] = 0; // 表示发送的是消息数据
                    Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
                    bool fff = true;
                    string strKey = "";
                    strKey = lbOnline.Text.Trim();
                    if (string.IsNullOrEmpty(strKey))   // 判断是不是选择了发送的对象;
                    {
                        MessageBox.Show("请选择你要发送的好友!!!");
                    }
                    else
                    {
                    dict[strKey].Send(arrSendMsg);// 解决了 sokConnection是局部变量,不能再本函数中引用的问题;
                    byte[] arrFile = new byte[1024 * 1024 * 2];
                    int length = fs.Read(arrFile, 0, arrFile.Length);  // 将文件中的数据读到arrFile数组中;
                    byte[] arrFileSend = new byte[length 1];
                    arrFileSend[0] = 1; // 用来表示发送的是文件数据;
                    Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
                    // 还有一个 CopyTo的方法,但是在这里不适合; 当然还可以用for循环自己转化;
                    //  sockClient.Send(arrFileSend);// 发送数据到服务端;
                    dict[strKey].Send(arrFileSend);// 解决了 sokConnection是局部变量,不能再本函数中引用的问题;
                       txtSelectFile.Clear(); 
                    }
                }
            }
            txtSelectFile.Clear();
        }

    
    }

实例下载地址

服务器和客户端(TCP发送消息、发送文件)

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警