初学Socket以下是关于Socket编程知识的点滴
先看一段代码:
//一般网络编程开头都会有的
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0){
return;
}
if( LOBYTE(wsaData.wVersion)!=1||
HIBYTE(wsaData.wVersion)!=1)
{
WSACleanup();
return;
}
//以上的功能主要是和WSA等进行交互,确定版本号等
接下来
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
socket(AF_INET,SOCK_STREAM,)函数它规定,它的AddrssFamily 为internet,它用的是SOCK_STREAM方式(即为TCP),最后0为默认的参数,它将自动为你选定一个协议。
调用成功,它将返回一个SOCKET描述符
接下来,是这一句
SOCKADDR_IN addrSrv;
查了一下MSDN解释原文如下
In the Internet address family, the SOCKADDR_IN structure is used by Windows Sockets to specify a local or remote endpoint address to which to connect a socket.
//sockaddr_in结构体的定义
struct sockaddr_in{
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
//其中in_addr定义如下
struct in_addr {
union {
struct{
unsigned char s_b1,
s_b2,
s_b3,
s_b4;
} S_un_b;//这个应该是表示struct union byte以字节表示
struct {
unsigned short s_w1,
s_w2;
} S_un_w;//以word表示
unsigned long S_addr;//以long表示
} S_un;
};
定义了SOCKADDR_IN之后,就可以对它进行赋值了
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//host to net long : )Maybe this
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
上面出现两个函数
inet_addr();和
htonl()以及将要在客户端出现的
htons();
关于inet_addr()函数MSDN解释的很清楚了:
"The inet_addr function converts a string containing an (Ipv4) Internet Protocol dotted address into a proper address for the IN_ADDR structure."
htonl()
"The htonl function converts a u_long from host to TCP/IP network byte order (which is big endian)."
而htons()则为
"The htons function converts a u_short from host to TCP/IP network byte order (which is big-endian)."
很明显,htonl()将long类型转换成网络字节序,而htons()则转换short类型.
需要注意的是S_addr是4个byte,而sin_port是2个byte,青年人网提示正是因为这个差异导致它们调用不同的函数
接着,做绑定和监听操作
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5);
看了好一会,才看明白,bind第二个参数的含义,当然,是自己理解的,不知对不对,欢迎指正
SOCKADD的结构体定义如下
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
按照MSDN的解释,头两个字节必须要是AddrssFamily,我想char sa_data[14]是起到一个占位符的作为,点了14个字节的空间。这么做,是因为addrssFamily有很多类型,各种类型数据不同,出于兼容的考虑定义如此。
bind()的第三个参数是指第二个参数的大小14个字节+2是16个字节,而sockadd_in我算了下,也是16个字节。
bind的意图很明显了"Use the bind function to establish the local association of the socket by assigning a local name to an unnamed socket." 其中的这个name就是指sockadd_in(其中有addr_family,port,addrsss)
责任编辑:小草