为什么socket通信接收数据少1字节. 诚心求解

thorhero 2009-07-09 04:47:06
小弟现在在写个网管程序管理一台设备,用SOCKET通信(设备服务端,网管程序客户端)。以前这设备用的老系统,通信没有故障,什么问题都没有。
现在设备换了新系统,问题就来了,该设备与windows 2000的通信没有问题(只有1台机器是2000的),和XP的机器通信就会少接一个字节,而最后个字节是一个分号,是一个命令的结束符。没它就会解析出问题。现在的解决办法是让设备每次多发1字节,然后如果是2000机器接到多的字节就把它处理掉。但是老板不满意我这种做法。

我用delphi 和C都写过客户端程序,测试时发送握手命令。连接新系统结果是,只要程序在2000上运行,就收80字节,在XP上运行,就收79字节。
然后又测试老系统。结果是,都收到80字节。

本来应该就判断是他新系统出的问题,但是用SNIFFER截包看来,设备确实发了80个字节。我仔细对照了包的每个字段,觉得完全没有问题啊,唯一的一点区别就是新系统发XP的时候TCP包头多了12字节的options-padding,这就会导致XP少收1字节?

当时去调设备的时候急,就截了SNIFFER的4张图,分别是老系统发2000,老系统发XP,新系统发2000,和新系统发XP的,不知道怎么把图放出来。这个问题听着就很荒唐,百度也搜不到任何信息,周围高手纷纷表示没听说过,我都不知道怎么办了。
...全文
582 63 打赏 收藏 转发到动态 举报
写回复
用AI写文章
63 条回复
切换为时间正序
请发表友善的回复…
发表回复
szw0024 2011-07-18
  • 打赏
  • 举报
回复
学习了 带外数据 和OOB模式 不错不错
thorhero 2009-07-10
  • 打赏
  • 举报
回复
[Quote=引用 45 楼 dengsf 的回复:]
我觉得问题出在紧急指针(Urgent pointer)那里。

貌似TCP的不同实现对紧急指针的理解略有不同,
有些是指向 紧急数据 最后一个字节,
有些是指向 紧急数据之后的第一个字节。

LZ的服务器应该不是 windows 系统吧。

主要问题是,
为什么新系统对普通的数据要用到紧急方式?
[/Quote]
恩,非常感谢。服务器是一台设备,以前老系统是PSOS,现在新系统是VXWORKS
我也不知道为什么用到了紧急方式,我也不知道怎么去控制这个,
是应该设备去控制,还是我这面客户端去控制?

求指教
dengsf 2009-07-10
  • 打赏
  • 举报
回复
我觉得问题出在紧急指针(Urgent pointer)那里。

貌似TCP的不同实现对紧急指针的理解略有不同,
有些是指向 紧急数据 最后一个字节,
有些是指向 紧急数据之后的第一个字节。

LZ的服务器应该不是 windows 系统吧。

主要问题是,
为什么新系统对普通的数据要用到紧急方式?
thorhero 2009-07-10
  • 打赏
  • 举报
回复
图能看到吗,现在不在实验室,什么时候我再弄个我程序截图发上来把
thorhero 2009-07-10
  • 打赏
  • 举报
回复
终于想了办法把图发出来

老系统发2000的


老系统发XP的


新系统发2000的


新系统发XP的
wentian719 2009-07-10
  • 打赏
  • 举报
回复
建议楼主下个通用的TCP测试程序
接收下,没问题的话就是你程序问题了
系统问题可能性很小
FigoZhu 2009-07-10
  • 打赏
  • 举报
回复
放wireshark抓的包上来,才好帮你分析。
thorhero 2009-07-10
  • 打赏
  • 举报
回复
怎么可能是代码问题嘛=。=

#include <stdio.h>
#include <string>
#include <winsock2.h>
#pragma comment(lib, "WS2_32.lib")
#define BUF_SIZE 1024
int main(int argc, char* argv)
{
int nRet = -1;
WSADATA wsaData;
SOCKADDR_IN serverAddr;
SOCKET socketC;
char ip[20];
//char sendbuf[BUF_SIZE] ="HAND-SHAKE:L000000000000001:MCP-2:R30014::;";
char recvbuf[BUF_SIZE];

int port = 5000;
/*printf("请输入断口号:\n");
scanf_s("%d",&port);*/

WSAStartup(MAKEWORD(1,1), &wsaData);

serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port);
printf("请输入设备IP:\n");
scanf_s("%s",ip);
getchar();
serverAddr.sin_addr.s_addr = inet_addr(ip);
socketC = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (connect(socketC, (SOCKADDR*)&serverAddr, sizeof(serverAddr))<0)
{
printf("connect failed!\n");
return -1;
}
for(;;)
{
printf("\nsend msg:HAND-SHAKE:L000000000000001:MCP-2:R30014::;");
getchar();
char sendstr[64] = "HAND-SHAKE:L000000000000001:MCP-2:R30014::;";
int length = strlen(sendstr);
if (send(socketC, sendstr, length, 0) <=0)
{
printf("send failed\n");
return -1;
}
for(;;)
{
nRet = recv(socketC, recvbuf, sizeof(recvbuf), 0);
if (nRet>0)
{
recvbuf[nRet] = '\0';
printf("\nget msg length:%d\nmsg:%s\n",nRet,recvbuf);
}
}
}
closesocket(socketC);
WSACleanup();
}

测试用的程序,2000下运行连设备返回80 和数据 后面有分号
XP下运行返回79 和数据 没分号了
dong364 2009-07-10
  • 打赏
  • 举报
回复
有点奇怪, 建议lz贴上关键代码, 否则无从判断
lllsui 2009-07-10
  • 打赏
  • 举报
回复
o
zqlong_sunday 2009-07-10
  • 打赏
  • 举报
回复
发送端一般多发一个字节如str.GetLength() + 1;最后一个字为空,这样接收端接收到的就会少一个字,是不是这样的缘故?
Tomzzu 2009-07-10
  • 打赏
  • 举报
回复
别一个包一个包的看, 可能是粘包的现象呢, 在发送方发送新数据前, 把缓冲区的未发送数据先发出去, 好像用函数setsocketopt来设置, 接收方recv也不是一次都能接收完的, 根据字节长度接收, 直到相同长度再将接收的数据拼接起来
thorhero 2009-07-10
  • 打赏
  • 举报
回复
感谢大家帮忙
这问题怪在为什么2000的机器上接收就正常,XP上就少一字节,也许不一定是2000和XP的问题。实验室有1台机器是2000的,这台机器接收正常,然后还有2台机器加我的笔记本是XP的,接收就少一字节。

还有就是老的设备用的老系统,他发过来的包不管XP和2000都收着是正常的。也排除了是系统原因

数据包里内容 头3字节是 0d 0a 0a,是用来做数据包识别的,然后就是些设备ID啊,时间这些信息了。中间有空格 20,也有换行 0d 0a,没有结束 00,最后包尾是 0d 0a 3b,就是一个换行一个分号。他老程序解析的时候是找这个分号做命令结束的位置,现在这最后一字节,就是这分号,收不到。(目前做法是多发一字节数据,处理时把分号后面的数据处理掉)
danny 2009-07-10
  • 打赏
  • 举报
回复
嗯,学习了..
ysysbaobei 2009-07-10
  • 打赏
  • 举报
回复
顶下
thorhero 2009-07-10
  • 打赏
  • 举报
回复
鬼知道他们怎么想起用这个来发数据哦,分不多,真想多给点的
thorhero 2009-07-10
  • 打赏
  • 举报
回复
泪目啊,搞整快1个星期,原来高手就一句话就点通了
设备还没试,我自己写了个服务端如果用send(socketC, sendbuf, length, MSG_OOB);发数据
客户端用recv(socketC, recvbuf, sizeof(recvbuf), 0);接就少一字节

recv(socketC, recvbuf, sizeof(recvbuf), MSG_OOB);可得那个分号,

悲剧,准备结帖了
大前置 2009-07-10
  • 打赏
  • 举报
回复
服务器端为设置紧急数据
可不可以这样认为
因为";"是必须的,没有整个报文就会出错,所以要保证";"到达呢
(个人理解)
thorhero 2009-07-10
  • 打赏
  • 举报
回复
有点眉目了 我去试下
rularys 2009-07-10
  • 打赏
  • 举报
回复
如果运行于该系统上的TCP应用程序行为正常的话,那么肯定是自己程序的问题,否则,就是系统的问题。

如过派出了系统的问题,那么可能你要仔细看一下你的程序了
加载更多回复(43)

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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