windows平台通信基础

 

·概要:

     对于windows平台的通信模型一般分为两个:客户端使用MFC中的接口、服务器端使用IOCP通信模型。

 

·要点:

基础:

    在windows中SOCKET是操作系统内部定义的数据结构。

    协议族在计算机中表示为一个整数—AF_INET,

              Socket类型为SOCK_STREAM和SOCK_DGRAM。

    涉及到一些地址相关的类型;

        sockaddr:

             作为函数参数而存在,在函数调用的时候需要类型转换;

        sockaddr_in:

             需要配置的数据类型,定义为:

                struct sockaddr_in{

                      short int sin_family;

                      unsigned short int sin_port;

                      struct in_addr sin_addr;

                      unsigned char sin_zero[8];

                };

              其中struct in_addr是另外定义的。

    相关头文件为:<winsock2.h>,同时需要连接动态库。

    初始化动态库:WSAStartup(MAKEWORD(2,2),&wsaData);

                  其中wsaData为WSADATA类型的变量。

    对应的库清理函数为WSACleanup()。

Socket函数原型:SOCKET socket(int af,int type,int protocol);

         出错返回INVALID_SOCKET。

         常用法为:SOCKET s=socket(AF_INET,SOCK_STREAM,0);

close socket函数:int closesocket(SOCKET s);

         成功返回0,否则返回SOCKET_ERROR。

connect函数:int connect(SOCKET s,const struct sockaddr* name,

                                  int namelen);

          成功返回0,否则返回SOCKET_ERROR。

                     对于非阻塞模式为WSAEWOULDBLOCK表示错误。

listen函数:int listen(SOCKET s,int backlog);

          成功返回0,否则返回SOCKET_ERROR。

bind函数:int bind(SOCKET s,const struc sockaddr* name,

                        int namelen);

          成功返回0,否则返回SOCKET_ERROR。

accept函数:SOCKET accept(SOCKET s,struct sockaddr* addr,

                                       int * addrlen);

          成功返回新连接的SOCKET,否则返回SOCKET_ERROR。

          其中addr和addrlen都是额外的返回值。

send函数--阻塞函数:int send(SOCKET s,const cha* buf,int len,

                                      int flags);

          成功返回发送成功的字节数,否则返回SOCKET_ERROR。

recv函数--阻塞函数:int recv(SOCKET s,char* buf,int len,int flags);

          成功返回接收的字节数,否则返回SOCKET_ERROR。

常用地址设置:SOCKADDR_IN ServerAddr;

                  ServerAddr.sin_family=AF_INET;

                  ServerAddr.sin_port=htons(8888);

                  ServerAddr.sin_addr.s_addr=inet_addr("127.0.0.1");

                  或ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY);

 

IOCP通信模型:

--基本原理:

    IOCP(I/O Completion Port--完成端口)内部采用的是前摄器模式。

    我理解的IOCP的工作过程是:

         首先需要一个接受新连接的循环:

                     接受新连接--将新连接绑定到IOCP--执行异步读数据

         然后是线程工作的循环:

                     检查完成的操作--判断完成操作的类型--执行分析判断操作

                        --执行异步循环

                 其中执行分析判断操作过程可能有异步写操作;

         在绑定socket和完成端口时就交由完成端口来记录socket;

         执行异步读取操作则可以保证socket不会丢失。

--数据结构:

    重叠端口:是操作系统内部用来在IOCP内部交流的数据结构。

                 常用法是作为struct结构的首元素--做指针类型转换;

    传输数据缓存—WSABUF,用于系统将完成的数据缓存;

    同时需要保存关联的SOCKET和记录完成操作的数据的数目;

    这些概念说起来很抽象,不过看代码的话就很好理解了。

--接口函数:

    主要有两个函数:

     1.HANDLE CreateIoCompletionPort(HANDLE FileHandle,

             HANDLE ExistingCompletionPort,ULONG_PTR CompletionKey,

             DWORD NumberOfConcurrentThreads);

          主要作用是创建IOCP和将SOCKET绑定到IOCP。

     2.BOOL GetQueuedCompletionStatus(HANDLE CompletinonPort,

             LPDWORD lpNumberOfBytes,PULONG_PTR lpCompletionKey,

             LPOVERLAPPED* lpOverlapped,DWORD dwMilliseconds);

           IOCP内部会管理线程池的,

                而线程则需要通过这个函数来查询完成的操作;

--注意事项:

    创建线程的数量一般配置为内核的数量或内核数量的2倍;

 

·小结:

    如果需要深入理解IOCP的话需要学习前摄器模式。

你可能感兴趣的:(windows)