TCP/IP Winsock编程要点

winsock之 TCP/IP的简单编程 //使用WinSock库之前,要做准备工作,即调用WSAStartUp初始化WinSock库。初始化后,才能使用WinSock库 //使用完WinSock库后,要做清理工作,即调用WSACleanUp清理 //这个工程的目的是:启动服务器监听客户端的连接请求,如果服务器收到客户端的连接请求,执行Accept接受客户端的连接请求返回一个与这个客户端通信的socket。然后使用这个socket与这 阅读详情

2003-3-28 12:54:21   YESKY   蒋勇

利用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方均已接收优先,适当控制时序就能实现

深入理解Winsock与TCP/IP在Windows下的网络通信 Windows网络编程接口,即Winsock,是Windows操作系统下用于网络通信的一套API。从其诞生至今,Winsock已经历多个版本的迭代,其中Winsock 2.0扩展了大量网络编程功能,以支持更复杂的应用程序需求。Winsock支持多种协议,尤其是广泛使用的TCP和UDP协议,使得开发者可以在Windows平台上创建客户端和服务器端的网络应用。客户端/服务器模型(Client/Server model)是一种分布式应用架构,其核心思想是将任务和服务分布在服务器端和客户端上。 阅读详情

相关推荐

LMS Virtual.Lab二次开发:声学仿真结果导出方法(VBScript、Python)

Siemens LMS Virtual.Lab 提供一套集成软件平台用以模拟机械系统的品质属性,如结构完整性、振动噪声、耐久性、系统动力学特性、驾驶的平顺性及操纵的稳定性等。

爱看书的小沐 6021

TCP/IP网络通信 WinSock编程

网络字节顺序: 网络中传输的数据使用的均是大尾方式, 大尾方式是 高位存放低字节,地位存放高字节。 windows提供了一些函数来处理本地机器的字节顺序和网络字节顺序的转换: u_short htons(u_short hostshort); u_long htonl(u_long hostlong); u_short ntohs(u_short netshort); u_

chijianxingfeng的专栏 1092

微处理器实验报告-实验四

实验四 可编程定时/计数器8253实验 一、实验要求 利用8086外接8253可编程定时/计数器,可以实现方波的产生。 二、实验目的 1、学习8086与8253的连接方法。 2、学习8253的控制方法。 3、掌握8253定时器/计数器的工作方式和编程原理

青竹小轩的博客 5112

TCP/IP Winsock编程要点(转)

1、快速通信   Winsock的Nagle算法将降低小数据报的发送速度,而系统默认是使用Nagle算法,使用 int setsockopt( SOCKET s, int level, int optname, const ch...

132

python入门:Anaconda和Jupyter notebook的安装与使用

一、安装和使用Anaconda 1、anaconda是什么? Anaconda在英文中是“巨蟒”的意思,与python的意思相近,它是python的包管理器和环境管理器。 2、为什么需要安装anaconda? 原因有以下几点: 附带一大批常用的数据科学包,方便立即开始处理数据 管理包 anaconda是在conda(一个包管理器和环境管理器)上发展来的;而conda可以很方便地对第三方的包进行安装、卸载和更新。 管理环境 conda可以为不同的项目建立不同的运行环境,避免不同的项目或包版本

PY洋洋 1万+

51单片机超声波测距数码管显示并报警(Proteus 仿真)

HC-SR04超声波 实物图 使用方法 1、给TRIG端口至少10us 的高电平信号 2、模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回 3、有信号返回,ECHO端口会输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间 计算的话这里就不考虑温度的影响直接用声速340m/s Proteus仿真 HC-SR04可以用Proteus中的SRF04代替 下面附上代码 ...

m0_46254883的博客 1万+

WinSock网络编程实用宝典(转载)

一、TCP/IP 体系结构与特点  1、TCP/IP体系结构  TCP/IP协议实际上就是在物理网上的一组完整的网络协议。其中TCP是提供传输层服务,而IP则是提供网络层服务。TCP/IP包括以下协议:            IP: 网间协议(Internet Protocol) 负责主机间数据的路由和网络上数据的存储。同时为ICMP,TCP,   UDP提供分组发送服务。用户进程通常

梦想---软件设计师 2401

这才是 Python 的正确玩法!用强化学习 (RL) 训练 AI 玩《王者荣耀》,胜率 90%!

大家打排位时,一定遇到过那种“意识神级、操作零失误”的对手,或者“走位呆滞、送人头”的队友。以前的“人机”是程序员写死的脚本(If 血量<20% Then 回城)。而现在的顶级 AI(如腾讯绝悟、OpenAI Five),是靠强化学习 (Reinforcement Learning)自己“左右互搏”练出来的。今天,我们不谈枯燥的数学公式,我将手把手教你用,搭建一个能玩 MOBA 游戏的 AI Agent。即使不能去 KPL 打职业,虐一下钻石局还是绰绰有余的!

BUG猿的博客 1182

WinSock网络编程实用宝典

WinSock网络编程实用宝典 收藏 一、TCP/IP 体系结构与特点   1、TCP/IP体系结构  TCP/IP协议实际上就是在物理网上的一组完整的网络协议。其中TCP是提供传输层服务,而IP则是提供网络层服务。TCP/IP包括以下协议:(结构如图1.1)(图1.1)   IP: 网间协议(Internet Protocol) 负责主机间数据的路由和网络上数据的存储。同时为IC

syf0582的专栏 274

Coverity本地增量C/C++代码检查(Linux)操作简介

Coverity 是一款精确的综合静态分析与应用安全测试 (SAST) 平台,它可以在编写代码时发现关键的缺陷和安全缺陷,防止它们变成安全漏洞、故障或维护缺陷。

1484

上位机1000条/秒数据不丢不卡:SQLite持久化队列最优方案实战

在上位机每秒1000条、1MB数据的场景下,SQLite做持久化队列是最优解可靠性拉满,ACID事务+WAL模式保证绝对不丢数据;性能完全够用,优化后每秒几千条没问题;轻量无依赖,只有一个.db文件;C#/.NET原生支持,代码简单易维护。只要按照上面的优化点和代码实现,完全能满足工业现场的需求,不用再担心数据丢失、存储卡采集的问题。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 485

(转)WinSock网络编程实用宝典

一、TCP/IP 体系结构与特点   1、TCP/IP体系结构   TCP/IP协议实际上就是在物理网上的一组完整的网络协议。其中TCP是提供传输层服务,而IP则是提供网络层服务。TCP/IP包括以下协议:(结构如图1.1) (图1.1)   IP: 网间协议(Internet Protocol) 负责主机间数据的路由和网络上数据的存储。同时为ICMP,TCP,   UDP提供分组发送...

weixin_30765319的博客 134

全国青少年信息素养大赛图形化(Scratch)编程考点总结

全国青少年信息素养大赛图形化(Scratch)编程考点总结

伶俐角少儿编程 382
上一篇: SOCKS 5协议详解
下一篇: Windows Socket API 使用经验
ManFred2ManFred
博客等级 码龄24年 2粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值