Windows网络编程总结(一)

原创 2004年10月29日 00:16:00

Windows网络编程总结(一)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

1. 关于bind

  INADDR_ANY 的具体含义是,绑定到0.0.0.0。此时,对所有的地址都将是有效的,如果系统考虑冗余,采用多个网卡的话,那么使用此种bind,将在所有网卡上进行绑定。在这种情况下,你可以收到发送到所有有效地址上数据包。

例如:

SOCKADDR_IN Local;

Local.sin_addr.s_addr = htonl(INADDR_ANY);

 

另外一种方式如下:

SOCKADDR_IN Local;

hostent* thisHost = gethostbyname("");

char* ip = inet_ntoa(*(struct in_addr *)*thisHost->h_addr_list);

Local.sin_addr.s_addr = inet_addr(ip); 

 在这种方式下,将在系统中当前第一个可用地址上进行绑定。在多网卡的环境下,可能会出问题。

 

最常见的方式:

const char LocalIP[] = "192.168.0.100";

SOCKADDR_IN Local;

Local.sin_addr.s_addr = inet_addr(LocalIP);

bind(socket, (LPSOCKADDR)&Local, sizeof(SOCKADDR_IN)

 

bind的安全问题:

       如果你在bind时,使用了INADDR_ANY那么,你将可以在所有有效的地址上进行监听,但是Socket有一个特性:可在同一端口上绑定多个Socket

       让我们看看下面的情况:假设你的系统只有一个IP192.168.0.100,你希望bind4096端口。对于下面的两种bind,当数据包到达时,谁会接收到呢?

Local.sin_addr.s_addr = htonl(INADDR_ANY);

Local.sin_addr.s_addr = inet_addr(“192.168.0.100”); 


       WinSocke
库是这样处理的:谁绑定的最明确,谁获取数据包。显然,第二种bind将获取到达的数据包。如果避免这种情况呢?使用SO_EXECLUSINEADDRUSE选项。需要注意的是,此选项在Windows NT 4 Service Pack 4以后(包括SP4)才可以使用。

示例代码:

#ifndef  SO_EXECLUSINEADDRUSE

#define  SO_EXECLUSINEADDRUSE  ((int)(~SO_REUSEADDR))

#endif

 

SOCKADDR_IN Local;

BOOL val = TRUE;

 

Local. sin_family = AF_INET;

Local. sin_port = htons(4096);

Local.sin_addr.s_addr = htonl(INADDR_ANY);

 

setsocketopt(socket,

           SOL_SOCKET,

           SO_EXECLUSINEADDRUSE,

           (char*)&val,

           sizeof(val));

 

bind(socket, (LPSOCKADDR)&Local, sizeof(SOCKADDR_IN)


 

2.关于connect

在阻塞模式下,当无法建立连接时connect的阻塞时间为20秒左右,可采用gethostbyaddr事先判断到服务主机的路径是否是通的,或者先ping一下对方主机的IP地址。

 

A、 采用gethostbyaddr阻塞时间不管成功与否为4秒左右。

hostent* remoteHost;

unsigned int addr;

 

addr = inet_addr("192.168.0.100");

remoteHost = gethostbyaddr((char *)&addr, 4, AF_INET);

 

if ( NULL != remoteHost )

{

   // Remote Host Online

}

 

B、 采用PING方式时间约2秒左右

 

3Nagle算法(TCP_NODELAY选项)

WinSock在默认情况下启用该算法。Nagle算法通过将未确认的数据存入缓冲区直到蓄足一个包一起发送的方法,来减少主机发送的零碎小数据包的数目。但对于某些应用来说,这种算法将降低系统性能。可使用TCP_NODELAY选项来将此算法关闭。不过,最好先测试关闭Nagle算法确实可以提高发送速度,再设置TCP_NODELAY选项,因为设置后对网络性能有明显的负面影响。另外需要注意,TCP_NODELAY是位于IPPROTO_TCP层的选项。

 

Nagle算法的不足之处主要有2点:

(1) 在限制数据报头部信息消耗的带宽总量的同时,是以牺牲网络延迟为代价的。

(2) 在发送方的缓冲区中,应用程序发送的数据包发生了粘滞的现象,即发送的若干数据包到接收方接收时变成一包,分不出各个包的界线。

 

前者因为数据被排队而不是立即发送的,因此不适用于需要快速响应时间的系统。后者则会影响到接收方的数据处理的准确性。

禁用Nagle算法:

int bNodelay = 1;

setsockopt( socket,

IPPROTO_TCP,

TCP_NODELAY,

(char *)&bNodelay,

sizoeof(bNodelay));

 

4TCPSegMentSize

  TCPSegMentSize是发送接受时单个数据报的最大长度,系统默认为1460Bytes

  在SOCK_STREAM方式下,如果单次发送数据超过1460,系统将分成多个数据报传送,在对方接受到的将是一个数据流,应用程序需要增加断帧的判断。当然可以采用修改注册表的方式改变1460的大小,但MicrcoSoft认为1460是最佳效率的参数,不建议修改。

在工控系统中,建议关闭Nagle算法,每次发送数据小于1460(推荐1400),这样每次发送的是一个完整的数据报,减少对方对数据流的断帧处理。

 

5SO_LINGER选项

SO_LINGER 延迟关闭连接,通过struct linger结构来进行控制。

struct linger {

   int l_onoff<;

   int l_linger;

}

l_linger  需要的超时值(以秒为单位)

l_onoff  为零时表示禁止SO_LINGER(此时,等同于SO_DONTLINGER

         为非零值时表示允许SO_LINGER

示例:

// 禁止延迟关闭 SO_DONTLINGER

struct linger li = {0, 0};

setsockopt(Socket, SOL_SOCKET, SO_LINGER, (char *)&li, sizeof(linger));

 

6.关于shutdown

int shutdown(

  SOCKET s,

  int how

);

shutdown函数用于在任何类型的套接字上禁止接收、禁止发送或禁止收发。

 

how参数有三种:

SD_SEND

    此时在该套接字上的后续的发送操作将被禁止。

SD_RECEIVE

    此时在该套接字上的后续的接收操作将被禁止。

SD_BOTH

    此时在该套接字上的后续的发送/接收操作都将被禁止。

注意事项:

   shutdown函数并不关闭套接字,且套接字所占有的资源将被一直保持到closesocket()调用。

   无论SO_LINGER设置与否,shutdown函数都不会阻塞。

《windows网络编程》中文高清PDF

  • 2008年05月07日 17:08
  • 11.74MB
  • 下载

windows网络编程-几种模式

 堵塞模式 1、tcp服务端 socket初始化:socket bind ip地址,端口信息 listen 启用监听 accept:等待连接 send,recv数据 2、tcp客户...
  • hjing1988
  • hjing1988
  • 2016年10月10日 09:16
  • 1327

Windows 网络编程

编程模型 7.1 基于 TCP -- 服务器 1,创建一个 socket ,用函数 socket() ; 2,绑定 IP 地址、端口等信息到 socket 上,用函数 bind() ; 3,设...
  • lhl1158612009
  • lhl1158612009
  • 2014年07月31日 17:22
  • 1213

Windows网络编程学习笔记(1) 编写一个Winsock基本框架

学习Winsock编程时的学习笔记,本章将介绍Winsock基本框架,Winsock 的作用,Winsock的环境设置, WSADATA结构体,不同平台下的Winsock版本,最基本的Winsock框...
  • Raito__
  • Raito__
  • 2016年05月10日 18:45
  • 2231

windows socket 网络编程

例子代码就在我的博客中,包括六个UDP和TCP发送接受的cpp文件,一个基于MFC的局域网聊天小工具工程,和此小工具的所有运行时库、资源和执行程序。代码的压缩包位置是http://www.blogja...
  • xxbsky520
  • xxbsky520
  • 2011年01月24日 14:47
  • 22503

Windows网络编程 经典教材(第二版)

  • 2016年03月22日 09:37
  • 10.41MB
  • 下载

Windows网络编程

第一章 序言               我写这个专题的目的,一方面是为了通过对网络编程再一次系统的总结,提高自己的网络编程水平,特别是Windows下的网络编程水平。同时,我也希望,能为众多初学网络...
  • michelsn
  • michelsn
  • 2007年12月13日 16:58
  • 21313

Windows网络编程(第二版)

  • 2016年01月22日 16:57
  • 10.36MB
  • 下载

Windows网络编程

第一章 序言          我写这个专题的目的,一方面是为了通过对网络编程再一次系统的总结,提高自己的网络编程水平,特别是Windows下的网络编程水平。同时,我也希望,能为众多初学网络编程的...
  • lgh1992314
  • lgh1992314
  • 2016年09月20日 08:16
  • 742

Windows网络编程(基础篇1)

Windows网络编程(基础篇1) Winsock是一种网络编程接口,不是协议。 除了WSAStartup、WSACleanup、WSARecvEx、WSAGetLastError属于W...
  • zt_xcyk
  • zt_xcyk
  • 2017年03月10日 15:21
  • 574
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Windows网络编程总结(一)
举报原因:
原因补充:

(最多只允许输入30个字)