C#-多线程和Socket网络编程-C/S传输文件(完結)

展示通信結果:

C#-多线程和Socket网络编程-C/S传输文件(完結)_第1张图片

上一篇实现了客户端和服务器通信详细:
点这看上一篇:传送门

服务器和客户端通信也是相同的道理,但是有一个问题,不只有一个客户端连服务器所以增加了一点改动:增加一个ComboBox来选择与之通信的ip地址,选择后可以与之通信。
具体步骤:
1.建一个键值对集合存放IP地址和端口号
2.点击事件调用Combo Box被选中的IP与之通信
源码:
集合:

//将远程连接的客户端的IP地址和Socket存入集合中
Dictionary<string, Socket> dicScoket = new Dictionary<string, Socket>();

点击事件:

/// 
        /// 服务器给客户端发送消息
        /// 
        /// 
        /// 
        private void button4_Click(object sender, EventArgs e)
        {
            string str = txtMsg.Text;
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
            //获取用户在下拉框选中的IP地址
            string ip = cboUsers.SelectedItem.ToString();
            dicScoket[ip].Send(buffer);
            //socketSend.Send(buffer);
        }

那么在这一节开始传输文件

传输文件

传文件对方需要知道接受的是文件还是文字

  • 那么就用到了设计协议
    • 要把传递的字节数组前边都加上一个字节作为标识。比如:0代表文字,1代表文件
    • 即:文字:0+文字(二进制表示)
    • 文件:1+文件的二进制信息

在选择文件按钮的点击事件中加选择文件功能

private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = @"C:\Users";
            ofd.Title = "请选择要发送的文件";
            ofd.Filter = "所有文件|*.*";
            ofd.ShowDialog();
            txtPath.Text = ofd.FileName;
        }

发送文件的点击事件

private void button3_Click(object sender, EventArgs e)
        {
            //获得要发送的路径
            string path = txtPath.Text;
            using (FileStream fsRead=new FileStream(path,FileMode.Open,FileAccess.Read))
            {
                byte[] buffer = new byte[1024*1024*5];
                int r = fsRead.Read(buffer, 0, buffer.Length);
                List<byte> list = new List<byte>();
                list.Add(1);
                list.AddRange(buffer);
                byte[] newBuffer = list.ToArray();
                try
                {
                    dicScoket[cboUsers.SelectedItem.ToString()].Send(newBuffer, 0, r + 1, SocketFlags.None);
                }
                catch//没选IP
                {

                    MessageBox.Show("选IP啊");
                }
                
            }
        }

另外一方选择接收文件:
分别约定了三个事件:

  • 0,是文字
  • 1,是文件
  • 2,是震动
    - 震动的实现就是使用Point让form框以两个不同的坐标来回动就可以了
void Recive()
        {
            while (true)
            {
                byte[] buffer = new byte[1024 * 1024 * 3];
                //实际接收到的有效字节数
                int r = socketSend.Receive(buffer);
                //判断是否有数据没有直接结束
                if (r == 0)
                {
                    break;
                }
                //取到传过来的第一位
                int n = buffer[0];
                //根据约定的协议 判断传过来是什么
                if (n == 0)
                {
                    //发送的是文字消息
                    //GetString(buffer, 1, r-1)范围变换了
                    //buffer长度多了一个数字 那就跳过【0】从buffer【1】开始 长度是-1
                    string str = Encoding.UTF8.GetString(buffer, 1, r - 1);
                    ShowMsg(socketSend.RemoteEndPoint + ":" + str);
                }
                else if (n == 1)
                {
                    SaveFileDialog sfd = new SaveFileDialog();
                    sfd.InitialDirectory = @"C:\Users";
                    sfd.Title = "请选择要保存的文件";
                    sfd.Filter = "所有文件|*.*";
                    sfd.ShowDialog(this);
                    string path = sfd.FileName;
                    try
                    {
                        using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
                        {
                            fsWrite.Write(buffer, 1, r - 1);
                        }

                    }
                    catch//不选文件出的问题
                    {

                        MessageBox.Show("选文件啊");
                    }
                    MessageBox.Show("保存成功");
                }
                else if (n == 2)
                {
                    ZD();
                }
            }
        }

你可能感兴趣的:(笔记,网络,c#,c语言)