传输连续空格导致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;
}

...全文
520 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端有些问题,空格并不是什么特殊的字符,应该没有啥区别。
内容概要:本文基于Matlab/Simulink平台,对电励磁同步电机在异步牵入、稳态运行及能耗制动三个阶段的全周期动态特性进行建模仿真与系统研究。研究构建了完整的电机数学模型与仿真系统,重点分析了电机从异步启动到同步运行的过渡过程、稳态运行时的电磁与机械性能,以及执行能耗制动时的减速特性与能量耗散机理。通过仿真,揭示了励磁电流、负载转矩与转速在不同工况下的动态响应规律与耦合关系,为电机的控制策略设计与性能优化提供了理论依据和数据支持。; 适合人群:具备电机学、电力电子与电力拖动基础知识的电气工程及相关专业的研究生、科研人员与工程技术人员。; 使用场景及目标:①研究电励磁同步电机的启动特性,解决异步牵入过程不稳定或失败的问题;②分析电机在不同负载下的稳态运行性能,优化运行效率;③设计和验证能耗制动策略,精确控制制动过程的减速时间和能量消耗。; 阅读建议:在学习过程中,应结合电机的基本原理,深入理解仿真模型中各模块(如电机本体、励磁控制、负载模型)的搭建逻辑,并通过调整仿真参数(如励磁电压、负载大小)来观察和分析系统动态响应,以加深对电机全周期运行特性的理解。
内容概要:通过介绍短时倒谱(Cepstrogram)计算方法,开展时-倒频分析研究,深入探讨倒谱分析机理、短时倒谱构建逻辑及时-倒频分析的内涵。文中系统对比了时-倒频分析与全局倒谱、传统时频分析方法的差异,阐明其在卷积特征解耦、非平稳信号跟踪、微弱周期特征增强及多维特征融合方面的技术优势,并分析其在语音识别、机械故障诊断、音频处理和非平稳时序信号分析中的典型应用,同时指出其在分辨率、计算复杂度等方面的局限性并提出优化方向。; 适合人群:具备一定信号处理或数据分析基础,从事机械、通信、声学或自动化等领域研究的研发人员及研究生。; 使用场景及目标:① 掌握短时倒谱与时-倒频分析的理论基础与实现方法;② 应用于语音信号处理、机械设备故障诊断、音频相似性检测等工程实践;③ 对比传统方法,提升对复杂非平稳信号中隐含周期特征的识别能力; 阅读建议:此资源以Matlab代码实现为核心,强调理论与实践结合,建议读者在理解核心算法原理的基础上,动手运行代码并调试参数,结合具体应用场景深化对方法适用性与局限性的认识。
摘 要 在数字经济与保险行业深度融合的背景下,传统保险服务普遍存在流程繁琐、信息不对称、线下办理效率低、管理成本高、理赔不透明等问题,已难以适应用户便捷化服务需求与行业数字化发展趋势。推动保险业务线上化、服务智能化、管理平台化,成为提升保险服务质量与运营效率的关键路径。 本文以在线保险服务与管理平台为研究对象,依据软件工程规范,采用 Spring Boot + Vue.js 前后端分离架构,结合 MySQL 数据库完成系统设计与实现。平台面向普通用户与管理员两类角色,涵盖注册登录、保险产品展示、在线投保、智能核保、保单管理、理赔申请、消息通知、保险知识科普、后台管理及数据统计等核心功能,实现保险服务全流程线上化、投保便捷化、保单管理智能化、理赔过程透明化、后台运营高效化。 系统依次完成需求分析、总体设计、详细设计、功能实现与全面测试。测试结果表明,平台在功能完整性、接口响应性能、数据安全防护及多浏览器兼容性方面均达到设计目标,运行稳定可靠。该平台可有效改善传统保险服务痛点,提升用户体验与管理效率,可为保险行业数字化转型提供实用的工程实践参考。 关键词:在线保险;服务平台;Spring Boot;Vue.js;前后端分离;保险数字化

3,881

社区成员

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

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