传输连续空格导致socket网络延时

xinhua0910 2014-06-20 07:11:09

最近测试,发现交易有时成功有时超时,这两天查询总结发现现状如下:
客户端:在异地,通过专线连到我方服务器(双方不同网段)
客户端系统:XP
服务端系统:linux
现状:
1. 只要客户端发的字符串中连续空格过多时,服务器端recv接收信息时就要好几秒(是通过recv后的时间减去accept后的时间得出消耗的时间。发连续40个空格时不到1秒,80个空格时要8秒,200多空格时要几十秒);
2. 如果发的不是连续空格,哪怕是几千个字节也是秒收秒回一秒内搞定;
3. 如果在内网同网段收发,哪怕多少个空格也是一秒内搞定,不会超时。

现在怀疑是不是网络设置哪里有问题,又或者是网络设备问题,但网络工作人员也没查到什么异常。不知各位有没有碰到类似情况,麻烦各位了

(由于担心是应用系统的问题,我是单独写了很简单的socket客户端和服务器端来测试,因此不会涉及系统应用逻辑问题。)

测试服务端日志情况:
第一笔70个长度,中间4个空格,秒杀
第二笔101个长度,中间有40个空格,秒杀
第三笔141个长度,中间有80个空格,接收信息就用时8秒
/usr/xxx/tmp 1259> ./a.out
socket created .
socked id: 3
connected.
local port:3995
listening...
Fri Jun 20 15:59:30 2014
[7096]accept a new connection:4[162.61.12.29]
Fri Jun 20 15:59:30 2014
[7098]收到消息: [70][0001AINQ0222000100000000000000000000000O0619161641000028021 1]
send OK
goto END

Fri Jun 20 16:00:57 2014
[7096]accept a new connection:4[162.61.12.29]
Fri Jun 20 16:00:57 2014
[7102]收到消息: [101][0001AINQ0222000100000000000000000000000O0619161641000028021 40]
send OK
goto END

Fri Jun 20 16:01:43 2014
[7096]accept a new connection:4[162.61.12.29]
Fri Jun 20 16:01:51 2014
[7105]收到消息: [141][0001AINQ0222000100000000000000000000000O0619161641000028021 80]
send OK
goto END

socket客户端(XP下的VC程序)如下:
#include <stdio.h>
#include<WINSOCK2.H>

#pragma comment(lib,"ws2_32.lib")

#define PORT 3995
#define REMOTE_IP "163.1.8.128"

int main(int argc,char *argv[])
{
int s ,iRcv=0;
struct sockaddr_in addr ;
char mybuffer[1024];

WSADATA wsaData = {0};
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
printf("WSAStartup failed.\n");
exit(-1);
}


if( (s=socket(AF_INET,SOCK_STREAM,0))<0 ) /*建立一个socket。*/
{
perror("socket");
printf("socket err [%d][%d]\n", s, WSAGetLastError());
exit(1);
}
else
{
printf("socket created .\n");
printf("socked id: %d \n",s);
}
memset(&addr, 0, sizeof(addr)); /*设置addr的信息。*/
addr.sin_family =AF_INET;
addr.sin_port=htons(PORT);
addr.sin_addr.s_addr=inet_addr(REMOTE_IP);
if(connect(s,&addr,sizeof(addr))<0) /*连接到远程服务器。*/
{
perror("connect");
printf("socket err [%d][%d]\n", s, WSAGetLastError());
close(s);
exit(1);
}
else /*输出信息。*/
{
printf("connected ok!\n");
printf("remote ip:%s\n",REMOTE_IP);
printf("remote port:%d\n",PORT);
}


strcpy(mybuffer, "0001AINQ0222000100000000000000000000000O0619161641000028021 030000005000100000000000021000000 62135600104000018008113EA0");

if(-1 == send(s, mybuffer, strlen(mybuffer), 0))
{
printf("send err!!!\n");
close(s);
exit(-1);
}
printf("send ok \n");

if(-1 == (iRcv = recv(s, mybuffer, sizeof(mybuffer), 0)))
{
printf("recv err!!!\n");
close(s);
exit(-1);
}
else
{
printf("[%d]收到消息: [%d][%s]\n", getpid(), iRcv, mybuffer);
}

getch();
close(s);
return 0;
}


socket服务端(Linux)如下:
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <time.h>

#define IPADDR "127.0.0.1"
#define PORT 3995
#define MAX 10

int main()
{
int iSocket, iSocket2, iRet, iAddrLen;
int iRcv=0;
char szBuf[2048];
struct sockaddr_in stAddr;
const int reuse = 1;
struct tm *ptr;
time_t loctime;

signal(SIGCLD,SIG_IGN);


if((iSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("socket err!\n");
exit(-1);
}
else
{
printf("socket created .\n");
printf("socked id: %d \n",iSocket);
}


if(iRet = setsockopt(iSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)))
{
printf("setsockopt err![%d][%d]\n", iRet, errno);
close(iSocket);
exit(-1);
}

memset(&stAddr, 0, sizeof(stAddr));
stAddr.sin_family =AF_INET;
stAddr.sin_port = htons(PORT);
stAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if((iRet = bind(iSocket, &stAddr, sizeof(stAddr))) < 0)
{
printf("bind err![%d][%d]\n", iRet, errno);
close(iSocket);
exit(-1);
}
else
{
printf("connected.\n");
printf("local port:%d\n",PORT) ;
}

if((iRet = listen(iSocket, 3)) < 0)
{
printf("listen err![%d]\n", iRet);
goto ERR;
}
else
{
printf("listening...\n");
}

iAddrLen = sizeof(stAddr);

while(1)
{
if((iSocket2 = accept(iSocket, &stAddr, &iAddrLen)) < 0)
{
printf("accept err![%d][%d][%s]\n", iSocket2, errno, strerror(errno));
goto ERR;
}
else
{
loctime=time(NULL);
ptr=localtime(&loctime);
printf(asctime(ptr));
printf("[%d]accept a new connection:%d[%s]\n", getpid(), iSocket2, inet_ntoa(stAddr.sin_addr));
}

if((iRet = fork()) < 0)
{
printf("fork err! \n");
goto ERR;
}
else if(iRet > 0)
{
// printf("Let Son To Recieve It,I Continue To accept\n");
close(iSocket2);
continue;
}

memset(szBuf, 0, sizeof(szBuf));
if(-1 == (iRcv = recv(iSocket2, szBuf, sizeof(szBuf), 0)))
{
printf("recv err!!![%d][%s]\n", errno, strerror(errno));
goto ERR;
}
else
{
loctime=time(NULL);
ptr=localtime(&loctime);
printf(asctime(ptr));
printf("[%d]收到消息: [%d][%s]\n", getpid(), iRcv, szBuf);
}

memset(szBuf, 0, sizeof(szBuf));
strcpy(szBuf, "快点好吧,受不了啦");
if(-1 == send(iSocket2, szBuf, strlen(szBuf), 0))
{
printf("send err!!!\n");
goto ERR;
}
else
{
printf("send OK\n");
}

goto END;
}

ERR:
close(iSocket);
close(iSocket2);
printf("server ERR\n");
return -123;
END:
close(iSocket);
close(iSocket2);
printf("goto END\n");
return 0;
}

...全文
497 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
xinhua0910 2014-08-20
  • 打赏
  • 举报
回复
谢谢两位回复,不过,都没什么价值。另外,赵老师,你的观点我知道,只是我们不是专门写传输工具的,而是特定环境的通信,所以不需要处理那么复杂。 回正题: socket通讯连接空格就导致接收耗时好几秒甚至几十秒的情况,公司网络人员也查了半个月,改过一堆的参数,都没有查出来。不过总结发现,走联通网络时没有问题,走电信网络时就延时。 后来找设备供应商一起查,也没有查到问题所在。最后,让设备商换了台“协议转换器”(好像是光纤转135什么的设备),就没有这个问题了。 至次,问题也算解决了。只是不知道问题原因
赵4老师 2014-06-23
  • 打赏
  • 举报
回复
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
xinhua0910 2014-06-23
  • 打赏
  • 举报
回复
给自己顶一下,有没有大牛碰到,求教了
碼上道 2014-06-21
  • 打赏
  • 举报
回复
可以在服务端调试一下,看看是哪个处理耗时间。 你在父进程关闭socketid,这个我感觉是不行了,如果子进程处理快,可能没有问题,但是对于复杂网络肯定是有问题的。
xinhua0910 2014-06-20
  • 打赏
  • 举报
回复
引用 1 楼 jerry_dqh 的回复:
else if(iRet > 0) { // printf("Let Son To Recieve It,I Continue To accept\n"); close(iSocket2); continue; } 父进程不能关闭socketid吧。不然子进程如何关闭啊, 总体来看server端有些问题,空格并不是什么特殊的字符,应该没有啥区别。
server端没问题,客户端发连续几十个空格就有问题,如果不发空格,发多少就正常; 如果把客户端放内网,随便发多少空格都没有问题。唯独客户端在异地时向服务器发连续几十个空格时recv时间就长了,发非空格时上千个字节都是秒杀
碼上道 2014-06-20
  • 打赏
  • 举报
回复
else if(iRet > 0) { // printf("Let Son To Recieve It,I Continue To accept\n"); close(iSocket2); continue; } 父进程不能关闭socketid吧。不然子进程如何关闭啊, 总体来看server端有些问题,空格并不是什么特殊的字符,应该没有啥区别。
内容概要:本文围绕基于Python和Transformer模型的多变量风电功率预测展开研究,重点针对短期风电功率预测任务。研究采用深度学习中的Transformer架构,引入风速、温度、湿度等多种气象及运行变量作为输入特征,构建高精度预测模型。为进一步提升预测的稳健性与可靠性,研究结合近端梯度算法求解LASSO分位数回归,优化模型在不确定性环境下的输出表现,增强预测结果的置信区间估计能力。该技术是机器学习与新能源领域深度融合的典型应用,旨在提高风电并网的稳定性与电网调度的科学性。; 适合人群:具备Python编程基础,熟悉主流深度学习框架(如PyTorch或TensorFlow)的研究生、科研人员,以及从事新能源发电预测、电力系统调度、智能电网优化等相关工作的技术人员。; 使用场景及目标:①应用于风电场实际运行中的短期功率预测系统,辅助电网进行精准负荷调配与调度决策;②作为科研项目的技术蓝本,用于复现、改进或扩展基于Transformer的时间序列预测模型;③探索LASSO分位数回归与深度学习模型的融合机制,提升预测结果的概率性输出与风险评估能力。; 阅读建议:此资源适用于已掌握机器学习与深度学习基础知识的读者,建议结合所提供的代码实现进行动手实践,重点关注多变量数据的预处理流程、Transformer模型的结构设计与注意力机制实现、超参数调优策略,并尝试在不同风电数据集上验证模型的泛化性能与鲁棒性。
内容概要:本文档《STK入门手册》系统介绍了AGI公司开发的Satellite Tool Kit(STK)软件的基本用法与核心功能,涵盖用户界面操作、地图窗口设置、各类对象(如卫星、航天器、设施、传感器等)的创建与属性定义,以及高级分析模块如高精度轨道预测(HPOP)、长周期轨道内容概要:预测(LOP)、地形本文档为与高分辨率地图《STK入门手册》,介绍了Sat的应用。手册还详细说明了Scellite Tool Kit(STK)软件的基本用enarios的时间设置、单位法与核心功能,配置、数据库管理重点涵盖用户界面操作、地图窗口设置、场景及动画演示等功能,帮助用户进行全面(Scenario)管理的卫星系统仿真、卫星及各类与分析。;对象(如航天器、设施、传感器 适合人群:适用于等)的创建与刚接触STK的新属性配置。手册手用户以及具备详细说明了STK一定经验的卫星系统分析的专业技术特性,包括人员,尤其适合从事高精度轨道预测(HPOP)、长航天、遥感、周期轨道分析(LO通信等领域工程技术人员P)、地形与高分辨率地图模块和研究人员。;、姿态模拟与指向 使用场景及目标:①用于、数据可视化等功能卫星轨道设计、,并提供了对象管理覆盖分析、通、动画设置、单位路计算、传感器配置、数据库调建模等航天用等实用操作任务仿真;指导。附录还包含术语表、文件②支持复杂空间格式说明及高级技术注释。; 适合人群:从事环境下的高精度动力学建模与可视化卫星系统分析、航天分析,提升系统设计与决策效率工程、轨道设计;③辅助等相关领域的科研人员和技术教学培训与工程项目工程师,尤其适合初学者和有一定实践,实现从基础操作到高级经验的STK用户功能的全面掌握。。; 使用; 阅读建议:建议场景及目标:①用于学习和掌握结合STK软件STK软件的基础实际操作同步学习,重点关注操作与高级分析功能;②支持各章节中的属性卫星轨道仿真、覆盖设置与操作流程分析、通路,注意手册中标计算、传感器建注的Notes、模等航天任务的规划与评估;③Hints和Warnings以避免常见错误,辅助教学培训与推荐配合官方教程工程项目中的空间态势与数据库资源深化可视化与数据分析。理解。; 阅读建议:建议结合软件实际操作同步阅读,重点关注各章节中的属性设置、投影类型选择及高级模块说明,注意手册中标注的Notes、Hints和Warnings以避免常见错误。

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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