Socket Send问题

Shrek_MyCpp 2010-06-17 06:41:58
1. 服务器
由一个且只有一个线程,来发送。

while (1)
{
...
// 到发送消息队列里,取消息。
// 此处,通过log文件分析,每次str的值都是正确的。
int n = send(socket, str, MAX_ANSWER_LENGTH, 0);
Sleep(1);
}


2. 客户端
由一个且只有一个线程,来接收。

while(1)
{
char recvBuf[MAX_ANSWER_LENGTH + 1] = {0};
recv(m_socket, recvBuf, MAX_RECV_SQL_LENGTH, 0);
...
// 此处,通过log文件分析,recvBuf可能有误。
}


现象:
当服务器和客户端,同时运行与本地时,没有问题。
但是,当远程客户端访问本地服务器时,recvBuf可能有误。
比如,服务器注释处,依次发送的str为 "111111", "222222", "333333"
在客户端注释处,解析的可能为"111111", " 222", " 333", " 222", " 333"。

请高手解释。
...全文
326 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
Antheus 2010-06-21
  • 打赏
  • 举报
回复
结账结账
Shrek_MyCpp 2010-06-21
  • 打赏
  • 举报
回复
以上的问题就此结束。
再请教一个问题:
阻塞的Send的返回值会不会小于欲发送的长度?
Shrek_MyCpp 2010-06-21
  • 打赏
  • 举报
回复
回31楼:
长度一致。
第二个建议详细点,好么
Shrek_MyCpp 2010-06-21
  • 打赏
  • 举报
回复
分数太少。大家见谅。见者有份啊。呵呵。
Shrek_MyCpp 2010-06-21
  • 打赏
  • 举报
回复
那好吧。谢谢各位捧场。
Shrek_MyCpp 2010-06-20
  • 打赏
  • 举报
回复
另外,我问的这个问题,当C/S在同一台机器上时,是不会出现的。只有远程,才会出现,比如城市1服务器和城市2客户端。
Shrek_MyCpp 2010-06-20
  • 打赏
  • 举报
回复
不要再谈结束符或者粘包的问题。这些不是我想问的。请针对我的问题回答。十分感谢。
Shrek_MyCpp 2010-06-20
  • 打赏
  • 举报
回复
谢谢25/26/27楼的好意。
我想再明确一下我的问题:
服务器send的固定长度的buf,客户端也recv固定长度的buf,且长度一致,请问客户端recv的buf里会不会出现非服务器发来的空字符。
TANG_XIAO_BIN 2010-06-20
  • 打赏
  • 举报
回复
1)查看buffer长度 MAX_ANSWER_LENGTH == MAX_RECV_SQL_LENGTH
2)改变接收、发送的环境,在UI线程里
Shrek_MyCpp 2010-06-19
  • 打赏
  • 举报
回复
听说MFC的Socket类有风险。 我现在都是用Windows的接口函数。
乱序的情况,暂时不考虑,可能是我的之前的代码问题。

我现在想问的是:
当服务器调用send不停发送 相等长度的 字符串(无空字符),
客户端调用recv会接收到其他的数据么, 比如空字符。
kemee 2010-06-19
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 shrek_mycpp 的回复:]

请教17楼!
如何 干脆让服务器端阻塞掉,等客户端返回一个OK再继续发???
[/Quote]

我这是很SB的方法,也不知道行不行的通,惭愧惭愧
改成一问一答的方式,重载CAsyncSocket类,随便自定义个数据格式,搞个标志位,服务端发1条数据,等Onreceive收到客户端的OK后继续发第二条数据,客户端收到一条数据处理完send一次OK给服务端
Shrek_MyCpp 2010-06-19
  • 打赏
  • 举报
回复
刚才log发现一个问题:
比如 发送 111111,222222。

在接收的时候,会出现这样的情况。
111111,
2222,

我想请教一下,在接收的222222前面的空字符是什么原因?
Shrek_MyCpp 2010-06-19
  • 打赏
  • 举报
回复
请教17楼!
如何 干脆让服务器端阻塞掉,等客户端返回一个OK再继续发???
周药师 2010-06-19
  • 打赏
  • 举报
回复
TCP经常会粘包
但不会乱包
检查一下你的业务逻辑,自己定义好协议,做好标识符,来解决粘包的问题
kemee 2010-06-19
  • 打赏
  • 举报
回复
干脆让服务器端阻塞掉,等客户端返回一个OK再继续发???这样一端无限循环猛发,我试了下,哪怕同时在一个机器上数据长了好像也会recv取错
Shrek_MyCpp 2010-06-19
  • 打赏
  • 举报
回复
...
谢谢15楼的执着



while(1)
{
char recvBuf[MAX_RECV_SQL_LENGTH + 1] = {0}; // type + data

recv(m_socket, recvBuf, MAX_RECV_SQL_LENGTH + 1, 0);

// // test.
//fseek(fp, 0, SEEK_END);
//fwrite(recvBuf, 1, MAX_RECV_SQL_LENGTH + 1, fp);
//fseek(fp, 0, SEEK_END);
//fwrite("\r\n", 1, 2, fp);
//fclose(fp);

LRESULT lRes = ::SendMessage(hWnd, WM_RECVDATA, 0, (LPARAM)recvBuf);

Sleep(1);
}
Antheus 2010-06-19
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 shrek_mycpp 的回复:]
多谢22楼指点。
有个问题想明确的是:
比如我发送分别发送11 和 22
那么11 和 22 之间会不会有别的东西,比如空字符。
[/Quote]
看你BUFF怎么送的。string自然有它自己的结尾字符,这也跟你送的长度有关系,比如你虽然送string,
但送的长度是strlen(x) - 1也可以跳过结尾字串。
你需要加强自己的调试能力,保证自己完全知道进入的输入是什么,收到的数据是甚么。
例如,你发送字符串str=“11”,长度用了strlen(str),其实真正的数据是0x31 0x31 0x00
建议你从HEX角度来处理所有数据,这样所有数据一视同仁。
许文君 2010-06-19
  • 打赏
  • 举报
回复
粘包了吧?先试试UDP看看,每发送一个在阻塞下,接受到确认消息在发
Shrek_MyCpp 2010-06-19
  • 打赏
  • 举报
回复
你对我19楼的问题的分析是对的。
粘包我基本上知道是怎么回事。
我想问的是:
11 和 22 之间, 会不会recv到空字符?
Shrek_MyCpp 2010-06-19
  • 打赏
  • 举报
回复
多谢22楼指点。
有个问题想明确的是:
比如我发送分别发送11 和 22
那么11 和 22 之间会不会有别的东西,比如空字符。
加载更多回复(16)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧