当前位置:   article > 正文

SOCKET通信——winsock编程_winsock2.h af_inet, sock_stream

winsock2.h af_inet, sock_stream

  Winsock是windows系统下利用Socket套接字进行网络编程的相关函数,是Windows下的网络编程接口。

       Winsock在常见的Windows平台上有两个主要的版本,即Winsock1和Winsock2。编写与Winsock1兼容的程序你需要引用头文件WINSOCK.H,如果编写使用Winsock2的程序,则需要引用WINSOCK2.H。此外还有一个MSWSOCK.H头文件,它是专门用来支持在Windows平台上高性能网络程序扩展功能的。使用WINSOCK.H头文件时,同时需要库文件WSOCK32.LIB,使用WINSOCK2.H时,则需要WS2_32.LIB,如果使用MSWSOCK.H中的扩展API,则需要MSWSOCK.LIB。正确引用了头文件,并链接了对应的库文件,你就构建起编写WINSOCK网络程序的环境了。

       一般来说,比较熟知的网络模型即OSI(Open system Interconnect)模型,它分为七层,即物理层,数据链路层,网络层,传输层,会话层,表示层以及应用层。而真正得到广泛应用的事TCP/IP 模型。在windows系统下,同样采用了TCP/IP模型进行不同主机以及不同网络间的通信。使用Winsock编程,即必须使用TCP/IP等相关协议进行通信。

在Winsock中,提供了TCP/IP协议下使用的套接字地址,即sockaddr_in结构体,在MSDN中查到其结构体的具体定义为:

其中:

  1. sin_family的值必须指定为AF_INET,代表所属地址家族是TCP/IP地址家族;
  2. sin_port代表端口号。我们知道,在TCP/IP协议,正是通过IP地址以及端口号实现端与端的通信。在TCP/IP协议中,有65536个端口号,因此指定为无符号short类型;
  3. in_addr同样是结构体。其结构为:

注:具体的使用方式以及注释都可查阅MSDN;

接下来本文将针对TCP协议具体实现进行简单的介绍。

针对上面的流程图,将对实现过程即相关函数进行介绍:

1、创建套接字:由于采用的是TCP协议,因此必须采用流式套接字,因为TCP协议采取的是字节流的方式进行传输数据的。

[cpp]  view plain  copy
 print ?
  1. socket s;  
  2. s=::socert(AF_INET,SOCK_SREAM,0);  

其中:


 最后一个参数指定为0的原因是因为在af中已经指定地址格式为TCP/IP协议规定的地址格式,因此最后一个参数协议类型指定为0;

2、绑定地址信息

使用函数bind()即可完成地址信息的绑定。这个过程完成的是套接字和地址信息的绑定。


参照代码: 
[cpp]  view plain  copy
 print ?
  1. sockaddr_in addr;  
  2. addr.sin_family=AF_INET;  
  3. addr.sin_port=htons(80);  
  4. addr.sin_addr.S_un.S_addr=INADDR_ANY;  
  5. ::bind(s,(sockaddr)&addr,sizeod(addr));  

3、作为TCP服务器必须处于监听状态,随时监听客户端的连接请求。这个过程是通过listen()函数实现的。

4、客户端发送连接请求。该函数于bind函数的结构类似。

这里的sockaddr定义的地址指针是服务器的地址指针;

5.服务器接受客户端的连接请求。实现函数为accept(),结构和connect()以及bind()类似,不同的是定义的结构指针应该为客户端的地址指针;

最后将TCP协议的实现代码贴在本文,实现平台是Visual c++6.0中建立控制台应用程序实现。

服务器代码:

[cpp]  view plain  copy
 print ?
  1. #include<winsock2.h>                        //包含头文件  
  2. #include<stdio.h>  
  3. #include<windows.h>  
  4. #pragma comment(lib,"WS2_32.lib")           //显式连接套接字库  
  5.   
  6. int main()                                  //主函数开始  
  7. {  
  8.     WSADATA data;                           //定义WSADATA结构体对象  
  9.     WORD w=MAKEWORD(2,0);                   //定义版本号码  
  10.     char sztext[]="欢迎你\r\n";                //定义并初始化发送到客户端的字符数组  
  11.     ::WSAStartup(w,&data);                  //初始化套接字库  
  12.     SOCKET s,s1;                            //定义连接套接字和数据收发套接字句柄  
  13.     s=::socket(AF_INET,SOCK_STREAM,0);      //创建TCP套接字  
  14.     sockaddr_in addr,addr2;                 //定义套接字地址结构  
  15.     int n=sizeof(addr2);                    //获取套接字地址结构大小  
  16.     addr.sin_family=AF_INET;                //初始化地址结构  
  17.     addr.sin_port=htons(75);  
  18.     addr.sin_addr.S_un.S_addr=INADDR_ANY;  
  19.     ::bind(s,(sockaddr*)&addr,sizeof(addr));    //绑定套接字  
  20.     ::listen(s,5);                              //监听套接字  
  21.     printf("服务器已经启动\r\n");              //输出提示信息  
  22.   
  23.     while(true)  
  24.     {  
  25.         s1=::accept(s,(sockaddr*)&addr2,&n);    //接受连接请求  
  26.         if(s1!=NULL)  
  27.         {  
  28.             printf("%s已经连接上\r\n",inet_ntoa(addr2.sin_addr));  
  29.             ::send(s1,sztext,sizeof(sztext),0); //向客户端发送字符数组  
  30.         }  
  31.         ::closesocket(s);                       //关闭套接字句柄  
  32.         ::closesocket(s1);  
  33.         ::WSACleanup();                         //释放套接字库  
  34.         if(getchar())                           //如果有输入,则关闭程序  
  35.         {  
  36.             return 0;                           //正常结束程序  
  37.         }  
  38.         else  
  39.         {  
  40.             ::Sleep(100);                       //应用睡眠0.1秒  
  41.         }  
  42.     }  
  43. }</windows.h></stdio.h></winsock2.h>  

客户端代码:

[cpp]  view plain  copy
 print ?
  1. #include<winsock2.h>                //包含头文件  
  2. #include<stdio.h>  
  3. #include<windows.h>  
  4. #pragma comment(lib,"WS2_32.lib")       //显式连接套接字库  
  5.   
  6. int main()                          //主函数开始  
  7. {  
  8.     WSADATA data;                       //定义WSADATA结构体对象  
  9.     WORD w=MAKEWORD(2,0);                   //定义版本号码  
  10.     ::WSAStartup(w,&data);                  //初始化套接字库  
  11.     SOCKET s;                       //定义连接套接字句柄  
  12.     char sztext[10]={0};  
  13.     s=::socket(AF_INET,SOCK_STREAM,0);          //创建TCP套接字  
  14.     sockaddr_in addr;                   //定义套接字地址结构  
  15.     addr.sin_family=AF_INET;                //初始化地址结构  
  16.     addr.sin_port=htons(75);  
  17.     addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");  
  18.     printf("客户端已经启动\r\n");              //输出提示信息  
  19.     ::connect(s,(sockaddr*)&addr,sizeof(addr));  
  20.     ::recv(s,sztext,sizeof(sztext),0);  
  21.     printf("%s\r\n",sztext);  
  22.     ::closesocket(s);                   //关闭套接字句柄  
  23.     ::WSACleanup();                     //释放套接字库  
  24.     if(getchar())                       //如果有输入,则关闭程序  
  25.     {  
  26.         return 0;                   //正常结束程序  
  27.     }  
  28.     else  
  29.     {  
  30.         ::Sleep(100);                   //程序睡眠  
  31.     }  
  32. }  
  33. </windows.h></stdio.h></winsock2.h>  
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/147137
推荐阅读
相关标签
  

闽ICP备14008679号