Socket编程小结

来源:互联网 发布:软件测试 郑人杰 编辑:程序博客网 时间:2024/04/29 19:26
初学Socket以下是关于Socket编程知识的点滴
先看一段代码:
  1. //一般网络编程开头都会有的
  2. WORD wVersionRequested;
  3. WSADATA wsaData;
  4. int err;
  5. wVersionRequested=MAKEWORD(1,1);
  6. err=WSAStartup(wVersionRequested,&wsaData);
  7. if(err!=0){
  8. return;
  9. }
  10. if( LOBYTE(wsaData.wVersion)!=1||
  11. HIBYTE(wsaData.wVersion)!=1)
  12. {
  13. WSACleanup();
  14. return;
  15. }
  16. //以上的功能主要是和WSA等进行交互,确定版本号等
接下来

  1. SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);

socket(AF_INET,SOCK_STREAM,)函数它规定,它的AddrssFamily 为internet,它用的是SOCK_STREAM方式(即为TCP),最后0为默认的参数,它将自动为你选定一个协议。
调用成功,它将返回一个SOCKET描述符
接下来,是这一句
  1. 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.

  1. //sockaddr_in结构体的定义
  2. struct sockaddr_in{
  3. short sin_family;
  4. unsigned short sin_port;
  5. struct in_addr sin_addr;
  6. char sin_zero[8];
  7. };
  8. //其中in_addr定义如下
  9. struct in_addr {
  10. union {
  11. struct{
  12. unsigned char s_b1,
  13. s_b2,
  14. s_b3,
  15. s_b4;
  16. } S_un_b;//这个应该是表示struct union byte以字节表示
  17. struct {
  18. unsigned short s_w1,
  19. s_w2;
  20. } S_un_w;//以word表示
  21. unsigned long S_addr;//以long表示
  22. } S_un;
  23. };
定义了SOCKADDR_IN之后,就可以对它进行赋值了

  1. addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//host to net long : )Maybe this
  2. addrSrv.sin_family=AF_INET;
  3. 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,正是因为这个差异导致它们调用不同的函数

接着,做绑定和监听操作

  1. bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
  2. listen(sockSrv,5);
看了好一会,才看明白,bind第二个参数的含义,当然,是自己理解的,不知对不对,欢迎指正

SOCKADD的结构体定义如下

  1. struct sockaddr {
  2. u_short sa_family;
  3. char sa_data[14];
  4. };

按照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)

原创粉丝点击