TCP/IP Winsock编程要点

本文介绍了TCP/IP Winsock编程的关键要点,包括禁用Nagle算法提高小数据包发送效率、调整TCP段大小避免帧断开、减少connect函数在网络故障时的阻塞时间、解决recv/send阻塞问题、改变TCP收发缓冲区大小、实现多IP地址绑定及监听,以及一种变种的Client/Server通信模式。
 
TCP/IP Winsock 编程要点
作者: Ackarlix
 
利用 Winsock 编程由同步和异步方式,同步方式逻辑清晰,编程专注于应用,在抢先式的多任务操作系统中 (WinNt Win2K) 采用多线程方式效率基本达到异步方式的水平,应此以下为同步方式编程要点。

   1 、快速通信

   Winsock Nagle 算法将降低小数据报的发送速度,而系统默认是使用 Nagle 算法 , 使用
int setsockopt(
SOCKET s,
int level,
int optname,
const char FAR *optval,
int optlen
);
函数关闭它

  例子:
SOCKET sConnect;
sConnect=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
int bNodelay = 1;
int err;
err = setsockopt(
sConnect,
IPPROTO_TCP,
TCP_NODELAY,
(char *)&bNodelay,
sizoeof(bNodelay));//
不采用延时算法
if (err != NO_ERROR)
TRACE ("setsockopt failed for some reason/n");;

   2 SOCKET SegMentSize 和收发缓冲
   TCPSegMentSize 是发送接受时单个数据报的最大长度,系统默认为 1460 ,收发缓冲大小为 8192
  在 SOCK_STREAM 方式下,如果单次发送数据超过 1460 ,系统将分成多个数据报传送,在对方接受到的将是一个数据流,应用程序需要增加断帧的判断。当然可以采用修改注册表的方式改变 1460 的大小,但 MicrcoSoft 认为 1460 是最佳效率的参数,不建议修改。
  在工控系统中,建议关闭 Nagle 算法,每次发送数据小于 1460 个字节(推荐 1400 ),这样每次发送的是一个完整的数据报,减少对方对数据流的断帧处理。
   3 、同步方式中减少断网时 connect 函数的阻塞时间
  同步方式中的断网时 connect 的阻塞时间为 20 秒左右,可采用 gethostbyaddr 事先判断到服务主机的路径是否是通的,或者先 ping 一下对方主机的 IP 地址。
   A 、采用 gethostbyaddr 阻塞时间不管成功与否为 4 秒左右。
  例子:
LONG lPort=3024;
struct sockaddr_in ServerHostAddr;//
服务主机地址
ServerHostAddr.sin_family=AF_INET;
ServerHostAddr.sin_port=::htons(u_short(lPort));
ServerHostAddr.sin_addr.s_addr=::inet_addr("192.168.1.3");
HOSTENT* pResult=gethostbyaddr((const char *) &
(ServerHostAddr.sin_addr.s_addr),4,AF_INET);
if(NULL==pResult)
{
int nErrorCode=WSAGetLastError();
TRACE("gethostbyaddr errorcode=%d",nErrorCode);
}
else
{
TRACE("gethostbyaddr %s/n",pResult->h_name);;
}

   B 、采用 PING 方式时间约 2 秒左右
  暂略
4
、同步方式中解决 recv send 阻塞问题
  采用 select 函数解决,在收发前先检查读写可用状态。
   A 、读
  例子:
TIMEVAL tv01 = {0, 1};//1ms 钟延迟 , 实际为 0-10 毫秒
int nSelectRet;
int nErrorCode;
FD_SET fdr = {1, sConnect};
nSelectRet=::select(0, &fdr, NULL, NULL, &tv01);//
检查可读状态
if(SOCKET_ERROR==nSelectRet)
{
nErrorCode=WSAGetLastError();
TRACE("select read status errorcode=%d",nErrorCode);
::closesocket(sConnect);
goto
重新连接(客户方),或服务线程退出(服务方) ;
}
if(nSelectRet==0)//
超时发生,无可读数据
{
继续查读状态或向对方主动发送
}

else
{
读数据
}

   B 、写
TIMEVAL tv01 = {0, 1};//1ms 钟延迟 , 实际为 9-10 毫秒
int nSelectRet;
int nErrorCode;
FD_SET fdw = {1, sConnect};
nSelectRet=::select(0, NULL, NULL,&fdw, &tv01);//
检查可写状态
if(SOCKET_ERROR==nSelectRet)
{
nErrorCode=WSAGetLastError();
TRACE("select write status errorcode=%d",nErrorCode);
::closesocket(sConnect);
//goto
重新连接(客户方),或服务线程退出(服务方) ;
}
if(nSelectRet==0)//
超时发生,缓冲满或 网络
{
//
继续查写状态或查读状态
}
else
{
//
发送
}

   5 、改变 TCP 收发缓冲区大小

  系统默认为 8192 ,利用如下方式可改变。
SOCKET sConnect;
sConnect=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
int nrcvbuf=1024*20;
int err=setsockopt(
sConnect,
SOL_SOCKET,
SO_SNDBUF,//
写缓冲,读缓冲为 SO_RCVBUF
(char *)&nrcvbuf,
sizeof(nrcvbuf));
if (err != NO_ERROR)
{
TRACE("setsockopt Error!/n");
}
在设置缓冲时,检查是否真正设置成功用
int getsockopt(
SOCKET s,
int level,
int optname,
char FAR *optval,
int FAR *optlen
);

   6 、服务方同一端口多 IP 地址的 bind listen

  在可靠性要求高的应用中,要求使用双网和多 网络 通道,再服务方很容易实现,用如下方式可建立客户对本机所有 IP 地址在端口 3024 下的请求服务。
SOCKET hServerSocket_DS=INVALID_SOCKET;
struct sockaddr_in HostAddr_DS;//
服务器主机地址
LONG lPort=3024;
HostAddr_DS.sin_family=AF_INET;
HostAddr_DS.sin_port=::htons(u_short(lPort));
HostAddr_DS.sin_addr.s_addr=htonl(INADDR_ANY);
hServerSocket_DS=::socket( AF_INET, SOCK_STREAM,IPPROTO_TCP);
if(hServerSocket_DS==INVALID_SOCKET)
{
AfxMessageBox("
建立数据服务器 SOCKET 失败 !");
return FALSE;
}
if(SOCKET_ERROR==::bind(hServerSocket_DS,(struct
sockaddr *)(&(HostAddr_DS)),sizeof(SOCKADDR)))
{
int nErrorCode=WSAGetLastError ();
TRACE("bind error=%d/n",nErrorCode);
AfxMessageBox("Socket Bind
错误 !");
return FALSE;
}
if(SOCKET_ERROR==::listen(hServerSocket_DS,10))//10
个客户
{
AfxMessageBox("Socket listen
错误 !");
return FALSE;
}
AfxBeginThread(ServerThreadProc,NULL,THREAD_PRIORITY_NORMAL);

  在客户方要复杂一些,连接断后,重联不成功则应换下一个 IP 地址连接。也可采用同时连接好后备用的方式。
   7 、用 TCP/IP Winsock 实现变种 Client/Server
  传统的 Client/Server 为客户问、服务答,收发是成对出现的。而变种的 Client/Server 是指在连接时有客户和服务之分,建立好通信连接后,不再有严格的客户和服务之分,任何方都可主动发送,需要或不需要回答看应用而言,这种方式在工控行业很有用,比如 RTDB 作为 I/O Server 的客户,但 I/O Server 也可主动向 RTDB 发送开关状态变位、随即事件等信息。在很大程度上减少了 网络 通信负荷、提高了效率。
  采用 1-6 TCP/IP 编程要点,在 Client Server 方均已接收优先,适当控制时序就能实现。
 
 
内容概要:本文档详细介绍了基于直驱永磁同步发电机(PMSG)的1.5MW风力发电系统在Simulink环境下的建模与仿真全过程,涵盖了风力机空气动力学模型、PMSG电磁特性建模、不可控整流与逆变电路、直流环节、空间矢量脉宽调制(SVPWM)技术以及核心控制策略的设计。重点实现了最大功率点跟踪(MPPT)控制以提升风能捕获效率,并构建了电压外环与电流内环协同工作的双闭环控制系统,通过仿真验证了系统在不同风速条件下稳定运行的能力及动态响应性能。; 适合人群:适用于具备电力系统、电机控制理论基础及Simulink仿真操作经验的研究生、科研人员和从事新能源发电系统开发的工程技术人员;特别适合正在进行风电系统建模、控制算法研究或完成相关毕业设计的专业人士。; 使用场景及目标:①深入理解直驱式PMSG风力发电系统的整体架构与工作机理;②掌握从物理部件建模到控制策略实现的完整Simulink仿真流程;③学习并复现MPPT控制、双闭环控制等关键技术方案;④为后续开展低电压穿越、并网稳定性分析、故障诊断等高级课题提供可靠的仿真平台支撑。; 阅读建议:建议结合Matlab/Simulink软件动手实践,逐模块搭建模型,重点关注各控制环节的参数设计与调试方法,同时可参照文中提供的其他风电相关资源进行拓展学习与对比分析。
已经博主授权,源码转载自 https://pan.quark.cn/s/868afdd63918 在信息技术领域中,前端开发构成了Web应用程序构建的关键环节,而登录注册页面则是用户与网站进行互动的起始界面。"150款web登录注册页面模板(附带效果图+源码)"这一资源为前端工程师们提供了一系列预先设计的界面组件,支持他们迅速构建既美观又实用的登录及注册界面,从而有效缩减开发周期并增强工作效率。 这些模板囊括了多样化的风格和设计潮流,涵盖了扁平化设计、Material Design、渐变色彩、暗黑模式等,能够适应不同项目的特定要求。在设计中强调用户体验,通过科学的布局安排,提升了表单的便捷操作性和可辨识度,并且不忽视视觉层面的吸引力。设计师通常会关注自适应设计,保证页面在多种设备(涵盖手机、平板及桌面电脑)上均能呈现良好的视觉效果。 这些模板均配备了源代码,使得开发者得以深入探究并个性化定制每个构成部分,涉及HTML的页面构造、CSS的样式修饰以及JavaScript的交互逻辑。HTML主要承担着页面基础结构的搭建,CSS用于实现页面美化与布局控制,JavaScript则常用于处理表单验证和交互效果。对于那些精通这三种技术的开发者而言,他们可以根据个人需求对模板进行功能扩展和样式调整。 在实际部署时,登录注册页面通常需要集成基础的输入项,例如用户名、密码、电子邮箱等,并且必须重视安全性考量,诸如密码强度指引、验证码系统等。除此之外,为了优化用户体验,还可能集成记住密码、自动填充、社交平台登录(例如微信、QQ、微博)等功能。 在开发阶段,前端工程师还需关注Web标准和无障碍访问(WCAG)规范,确保页面的通用友好性,这包括视障、听障或其他有特殊需求的用户群体。具体措施涉及标...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值