CSharp中Socket网络编程(二)重要bug修改

第一部分:整个通信过程梳理;文末附全套代码;



本篇为第二部分:重要bug完善



第三部分:消息类型编码:自定义通信协议



第四部分:全套代码


在第一部分:整个通信过程梳理中:有一个重要bug:多个客户端与服务器通信,服务器发送的消息只能被最新接入的客户端收到,其他客户端无法收到。不能实现点对点,端到端的通信。

为此在服务端我们预留了一个下拉列表来选择通信目标端。

思路是: 

看原来的代码:每当一个客户端接入之后,我们把都会创建一个新的socketSend来跟客户端进行通信socketSend = socketWatch.Accept();所以服务器每次只能给最新接入的客户端发送消息。之前接入的SocketSend被覆盖。

Socket socketSend;

void Listen(object o)
{
    Socket socketWatch = o as Socket;
    while (true)
    {
        try
        {
            // 等待客户端的连接,接受客户端的连接请求,并为新建连接创建一个负责通信的新的System.Net.Socket.Socket连接。
            socketSend = socketWatch.Accept();
            ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功");

            //开启一个新线程,不停的接受客户端发送过来的消息
            Thread th = new Thread(Recive);
            th.IsBackground = true;
            th.Start(socketSend);
        }
        catch { }
    }
}

解决方法:将客户端的IP和端口号保存到下拉列表中,那么每次给客户端发送消息时,由下拉列表中选定。

所以每当客户端接入之后,将客户端信息保存下来。并且将服务器中与客户端通信的socketSend信息也保存下来。保证每次指定SocketSend来实现点对点通信。

将ip地址和对应的socketSend保存下来,一一对应的数据结构就是键值对,字典。所以在外面新建一个Dictionary,供全局使用。

/// <summary>
/// 等待客户端的连接 并且创建与之通信用的Socket
/// </summary>
/// 
Socket socketSend;
Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();

void Listen(object o)
{
    Socket socketWatch = o as Socket;
    while (true)
    {
        try
        {
            // 等待客户端的连接,接受客户端的连接请求,并为新建连接创建一个负责通信的新的System.Net.Socket.Socket连接。
            socketSend = socketWatch.Accept();
            ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功");

            // 将接入的客户端的IP地址和端口号存入到下拉列表中;
            // 当选中客户端之后,对应的socketSend也要相应的去工作。
            // 将ip地址和对应的socketSend保存下来,一一对应的数据结构就是键值对,字典。所以在外面新建一个Dictionary,供全局使用。
            dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);

            // 将远程连接的客户端的IP地址和端口号存入到下拉列表中。等待选择;
            cboUsers.Items.Add(socketSend.RemoteEndPoint.ToString());

            //开启一个新线程,不停的接受客户端发送过来的消息
            Thread th = new Thread(Recive);
            th.IsBackground = true;
            th.Start(socketSend);
        }
        catch { }
    }
}

拿到对应关系之后,那么再给客户端发送消息时,首先需要拿到下拉框中选中的IP地址。原来的代码也需要修改。

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

如此实现了可以根据目标的地址,保留相应的socketSend来实现精准匹配通信。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值