使用 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;
}
似乎连续总是会丢失后面的,有大佬知道问题在哪吗?
1
hankai17 2023-07-17 10:34:50 +08:00
粘包警察在此
|
2
hankai17 2023-07-17 10:39:47 +08:00
是 tcp 吧
看看 send 返回值 不是 go 的协程模型吧 感觉上层调用 send 了 底层有缓存没有及时 flush? |
3
opengps 2023-07-17 10:43:59 +08:00
看起来就是粘包问题
|
4
exqibao OP |
5
coder001 355 天前
在 C#玩 TCP 当然是 Kestrel ,微软自家出品的 Socket 封装,客户端和服务端都能用,用上它之后再也不用自己操心缓冲区了,PDU 边界(低情商俗称:粘包分包)什么的更是雕虫小技
https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.server.kestrel.transport.sockets.socketconnectioncontextfactory.create?view=aspnetcore-8.0 |