zoukankan      html  css  js  c++  java
  • Socket通信(二)

    程序下载地址:

    http://download.csdn.net/detail/u010312811/9683748

    1.基本流程

    服务器:
    (1)用指定的端口号和服务器的IP建立一个EndPoint对象
    (2)建立一个Socket对象
    (3)用Socket对象的Bind()方法绑定EndPoint
    (4)用Socket对象的Listen()方法开始监听
    (5)接受客户端的连接,用Socket对象的Accept()方法创建新的Socket对象用于和请求的客户端进行通信
    (6)通信结束后一定要关闭Socket

    客户端:
    (1)用指定的端口号和服务器的IP建立一个EndPoint对象
    (2)建立一个Socket对象
    (3)用Socket对象的Connect()方法以上面建立的EndPoint对象作为参数,向服务器发出连接请求
    (4)如果连接成功,就用Socket对象的Send()方法向服务器发送信息
    (5)用Socket对象的Receive()方法接收服务器发来的信息
    (6)通信结束后需要关闭Socket

    2.功能及效果图: 

    • Server和Client进行封装,方便调用
    • 消息进行封装,消息收发利用Linq
    • 消息使用事件进行发布订阅,降低耦合度
    • 支持消息发送、文件发送(文件大小不超过10M)
    • 服务器端支持用户昵称,上下线提醒

    3.服务器功能介绍:

    (1)服务器开始监听:

    • 订阅消息接收事件
    • 订阅文件接收事件
    • 订阅用户的登陆、退出事件
     1    //服务器开始监听端口
     2    server.StartListen(txtIp.Text, int.Parse(txtPort.Text));
     3    //服务器接收到消息
     4    server.MessageReceived += server_MessageReceived;
     5    //服务器接收到文件
     6    server.FileReceived += server_FileReceived;
     7    //服务器订阅用户的登录退出事件
     8    server.UserLogIn += server_UserLogIn;
     9    server.UserLogOut += server_UserLogOut;
    10 
    11    txtMsgReceive.Text += "服务器开始监听!
    ";

    (2)消息的发送:

    • 获取需要发送的消息
    • 将消息进行封装
    • 获取需要接收数据的客户端IP
    • 发送消息
     1     //获取需要发送的消息
     2     string strMsg = txtMsgSend.Text;
     3     //填充数据结构
     4     MessageBase mb = new MessageBase();
     5     mb.UserName = "服务器";                          
     6     mb.MessageType = MessageType.Message;            //消息类型
     7     mb.Messages = Encoding.Default.GetBytes(strMsg); //发送的消息转换为字节数组
     8     mb.FileName = "";                                //发送消息,文件名填空
     9     //获取用户名和用户IP
    10     string name=lbOnlineList.SelectedItem.ToString();
    11     string ip=server.GetUserID(name);
    12     //发送消息
    13     if (name != "")
    14         server.SendMessage(ip, mb);
    15     else
    16         MessageBox.Show("错误!");

    (3)文件的发送:

    • 获取本地文件路径
    • 通过FileStream读取文件,并将文件保存为byte数组
    • 将消息进行封装
    • 获取需要接收数据的客户端IP
    • 发送消息
     1 //获取文件路径
     2 string filePath = txtSelectFile.Text;
     3 //发送消息
     4 using (FileStream fs = new FileStream(filePath, FileMode.Open))
     5 {
     6     byte[] arrFile = new byte[bufferSize];
     7     int length = fs.Read(arrFile, 0, arrFile.Length);
     8     byte[] arrFileSend = new byte[length];
     9     Array.Copy(arrFile, 0, arrFileSend, 0, length);
    10 
    11     MessageBase mb = new MessageBase();
    12     mb.UserName = "服务器";
    13     mb.MessageType = MessageType.File;                //消息类型
    14     mb.Messages = arrFileSend;                        //文件转换为字节数组
    15     mb.FileName = Path.GetFileName(filePath);         //文件名
    16     //获取用户名和用户IP
    17     string name = lbOnlineList.SelectedItem.ToString();
    18     string ip = server.GetUserID(name);
    19     //发送文件
    20     if (name != "")
    21         server.SendFile(ip, mb);
    22     else
    23         MessageBox.Show("错误!");
    24 }

    (4)消息的接收:

    • 获取消息的封装
    • 获取消息并处理数据
    1     string strMsg = Encoding.Default.GetString(mb.Messages);
    2     Action Update = () =>
    3         {
    4             txtMsgReceive.Text += string.Format("{0}[{1}]:
    {2}
    ",mb.UserName,DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"),strMsg );                  
    5         };
    6     //Invoke(Update);           //同步的方法
    7     BeginInvoke(Update);        //异步的方法

    (5)文件的接收:

    • 另存为对话框提示,获取保存的路径及文件名
    • 提取消息并进行处理
     1 Action Update = () =>
     2         {
     3             //弹出保存对话框
     4             SaveFileDialog sfd = new SaveFileDialog();
     5             sfd.FileName = mb.FileName;
     6             DialogResult dr = sfd.ShowDialog();
     7 
     8             if (dr == DialogResult.OK)
     9             {
    10                 //获取文件保存的路径
    11                 string fileSavePath = sfd.FileName;
    12                 //创建文件流,然后根据路径创建文件
    13                 using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
    14                 {
    15                     fs.Write(mb.Messages, 0, mb.Messages.Length);
    16                     MessageBox.Show("文件保存成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Hand);
    17                 }
    18             }
    19         };
    20     Invoke(Update);

    (6)有新用户登录:

    • 获取系统中的用户列表
    • 更新用户显示列表
     1     string[] users = server.GetUsers();
     2     Action Update = () =>
     3         {
     4             lbOnlineList.Items.Clear();
     5             for (int i = 0; i < users.Length; i++)
     6             {
     7                 lbOnlineList.Items.Add(users[i]);
     8             }
     9 
    10             lbOnlineList.SelectedIndex = 0;
    11         };
    12     Invoke(Update);

    (7)用户退出:

    • 获取系统中的用户列表
    • 更新用户显示列表
     1     string[] users = server.GetUsers();
     2     Action Update = () =>
     3     {
     4         lbOnlineList.Items.Clear();
     5         for (int i = 0; i < users.Length; i++)
     6         {
     7             lbOnlineList.Items.Add(users[i]);
     8         }
     9     };
    10     Invoke(Update);

    4.客户端功能介绍:

    (1)连接服务器:

    • 实例化一个客户端
    • 客户端连接到服务器
    • 订阅客户端的消息接收事件、文件接收事件
    1     client = new Client();
    2     client.ConnectServer(txtIp.Text, int.Parse(txtPort.Text));
    3     //客户端接收到消息
    4     client.MessageReceived += client_MessageReceived;
    5     //客户端接收到文件
    6     client.FileReceived += client_FileReceived;

    (2)消息的发送:

    • 获取需要发送的消息
    • 对消息进行封装
    • 向服务器发送消息
     1     //获取需要发送的消息
     2     string strMsg = txtSendMsg.Text;
     3     //填充数据结构
     4     MessageBase mb = new MessageBase();
     5     mb.UserName = txtName.Text;                       //用户名
     6     mb.MessageType = MessageType.Message;             //消息类型
     7     mb.Messages = Encoding.Default.GetBytes(strMsg);  //发送的消息转换为字节数组
     8     mb.FileName = "";                                 //发送消息,文件名填空
     9     //客户端向服务器发送消息
    10     client.SendMessage(mb);

    (3)文件的发送:

    • 获取本地文件路径
    • 通过FileStream读取文件,并将文件保存为byte数组
    • 将消息进行封装
    • 获取需要接收数据的客户端IP
    • 发送文件
     1 //获取文件路径
     2     string filePath = txtSelectFile.Text;
     3     //发送消息
     4     using (FileStream fs = new FileStream(filePath, FileMode.Open))
     5     {
     6         byte[] arrFile = new byte[bufferSize];
     7         int length = fs.Read(arrFile, 0, arrFile.Length);
     8         byte[] arrFileSend = new byte[length];
     9         Array.Copy(arrFile, 0, arrFileSend, 0, length);
    10 
    11         MessageBase mb = new MessageBase();
    12         mb.UserName = txtName.Text;                   //用户名
    13         mb.MessageType = MessageType.File;            //消息类型
    14         mb.Messages = arrFileSend;                    //文件转换为字节数组
    15         mb.FileName = Path.GetFileName(filePath);     //文件名
    16 
    17         client.SendFile(mb);
    18     }

    (4)消息的接收:

    • 获取消息的封装
    • 获取消息并处理数据
    1     string strMsg = Encoding.Default.GetString(mb.Messages);
    2     Action Update = () =>
    3         {
    4             txtReceiveMsg.Text += string.Format("{0}[{1}]:
    {2}
    ", mb.UserName, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), strMsg);   
    5         };
    6     //Invoke(Update);     //同步
    7     BeginInvoke(Update);  //异步

    (5)文件的接收:

    • 另存为对话框提示,获取保存的路径及文件名
    • 提取消息并进行处理
     1     Action Update = () =>
     2         {
     3             //弹出保存对话框
     4             SaveFileDialog sfd = new SaveFileDialog();
     5             sfd.FileName = mb.FileName; ;
     6             DialogResult dr = sfd.ShowDialog();
     7 
     8             if (dr == DialogResult.OK)
     9             {
    10                 string fileSavePath = sfd.FileName;//获取文件保存的路径
    11                 //创建文件流,然后根据路径创建文件
    12                 using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
    13                 {
    14                     fs.Write(mb.Messages, 0, mb.Messages.Length);
    15                     MessageBox.Show("文件保存成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Hand);
    16                 }
    17             }
    18         };
    19     Invoke(Update);
  • 相关阅读:
    记下mongoose(转载)
    vue vue-cli中引入全局less变量的方式
    单标签不支持 伪元素
    删除tppabs,href="javascript:if(confirm)...",、/*tpa=http://...
    系统字体放大导致rem布局错乱,解决方案,已通过测试
    IE条件注释
    hbase部署经验与坑总结
    ubuntu安装mysql 5.7
    静态代理和动态代理
    单例模式
  • 原文地址:https://www.cnblogs.com/imstrive/p/6064664.html
Copyright © 2011-2022 走看看