使用 C#的 HPSocket 的一个问题

297 天前
 exqibao

使用 hpSocket 写程序分服务端和客户端,服务端收到客户端的一个消息,服务端会响应多个信息给客户端,但客户端只收到部分信息,收到的包都是完整的。

服务端断点时,一个一个看客户端又能收到,关闭断点有低概率收到完整,大概率又收不完全。

其实循环里面只用发一次,调试故意发 5 次,至少收到 1 次,但没试过 5 次都全收到,除非卡着断点一个一个 Send 走。

            // 创建其他玩家
            foreach (var model in DALManager.Instance.UserDal.GetAllUserModel())
            {
                Server.Send(connid, MessageType.Type_User, MessageType.User_Create_S, model.ID, model.UserInfo.ModelID,
                    model.Point);
                Server.Send(connid, MessageType.Type_User, MessageType.User_Create_S, model.ID, model.UserInfo.ModelID,
                    model.Point);
                Server.Send(connid, MessageType.Type_User, MessageType.User_Create_S, model.ID, model.UserInfo.ModelID,
                    model.Point);
                Server.Send(connid, MessageType.Type_User, MessageType.User_Create_S, model.ID, model.UserInfo.ModelID,
                    model.Point);
                Server.Send(connid, MessageType.Type_User, MessageType.User_Create_S, model.ID, model.UserInfo.ModelID,
                    model.Point);
            }

封装的 Send 方法;

        public static void Send(IntPtr connid, byte type, int command, params object[] content)
        {
            Message message = new Message(type, command, content);
            byte[] bytes = Message.ToBytes(message);
            server.Send(connid, bytes, bytes.Length);
        }

hp-socket 的代码了;

    public bool Send(IntPtr connId, byte[] bytes, int length)
    {
      GCHandle gcHandle = GCHandle.Alloc((object) bytes, GCHandleType.Pinned);
      bool flag = HPSocket.Sdk.Server.HP_Server_Send(this.SenderPtr, connId, gcHandle.AddrOfPinnedObject(), length);
      this.SysErrorCode.Value = flag ? 0 : Sys.SYS_GetLastError();
      gcHandle.Free();
      return flag;
    }

似乎连续总是会丢失后面的,有大佬知道问题在哪吗?

958 次点击
所在节点    C#
5 条回复
hankai17
297 天前
粘包警察在此
hankai17
297 天前
是 tcp 吧
看看 send 返回值
不是 go 的协程模型吧 感觉上层调用 send 了 底层有缓存没有及时 flush?
opengps
297 天前
看起来就是粘包问题
exqibao
297 天前
@hankai17 @opengps 感谢,看视频没有粘包的处理过程,以为框架有粘包,客户端接收的包是分开的,检查包大小确实后面的包都合并一起了。
coder001
158 天前
在 C#玩 TCP 当然是 Kestrel ,微软自家出品的 Socket 封装,客户端和服务端都能用,用上它之后再也不用自己操心缓冲区了,PDU 边界(低情商俗称:粘包分包)什么的更是雕虫小技

https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.server.kestrel.transport.sockets.socketconnectioncontextfactory.create?view=aspnetcore-8.0

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/957313

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX