zoukankan      html  css  js  c++  java
  • WinSock编程基础

    一、套接字模式

      1、阻塞模式

          创建套接字时,默认是阻塞模式,对recv函数调用会使程序进入等待状态,知道接收到数据才返回。

      2、非阻塞模式:

         可以调用ioctlsocket函数显式地让套接字工作在非阻塞模式下。

    u_long ul = 1;
        SOCKET s = ::socket(AF_INET,SOCK_STREAM,0);
        ::ioctlsocket(s,FIONBIO,(u_long*)&ul);

    3、windows提供的I/O模型

        1、Select模型

               使用select函数来管理I/O

    #include "../../common/InitSock.h"
    #include <stdio.h>
    
    CInitSock initsock;
    
    int main(){
        
        USHORT nPort = 4567;
        SOCKET sListen = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        sockaddr_in sin;
        sin.sin_family = AF_INET;
        sin.sin_port = htons(nPort);
        sin.sin_addr.S_un.S_addr = INADDR_ANY; //服务端一般这样这是地址
    
        //绑定套接字到本地机器
        if(::bind(sListen,(sockaddr*)&sin,sizeof(sin)) == SOCKET_ERROR){
            printf("Failed bind()
    ");
            return -1;
        }
    
        //进入监听模式
        ::listen(sListen,5);
    
        //select模型处理过程
        //1)初始化一个套接字fdsocket,添加监听套接字句柄到这个集合
        fd_set fdsocket;  //所有可用套接字集合
        FD_ZERO(&fdsocket);
        FD_SET(sListen,&fdsocket);
    
        while(TRUE){
            //2)将fdsocket集合的一个拷贝fdRead传递给select函数
            //  当有事情发生时,select函数移除fdRead集合中没有未决I/O操作的套接字句柄,然后返回
            fd_set fdRead = fdsocket;
            int nRet = ::select(0,&fdRead,NULL,NULL,NULL);
            if(nRet > 0){
                //3)通过将原来fdsocket集合与select处理过的fdread集合比较
                //  确定有哪些套接字有未决I/O, 并进一步处理这些I/O
                for (int i = 0; i != (int)fdsocket.fd_count; ++i)
                {
                    if(FD_ISSET(fdsocket.fd_array[i],&fdRead)){
                        if(fdsocket.fd_array[i] == sListen){//(1)监听套接字接收到新连接
                            if(fdsocket.fd_count < FD_SETSIZE){
                                sockaddr_in addrRemote;
                                int nAddrLen = sizeof(addrRemote);
                                SOCKET sNew = ::accept(sListen,(SOCKADDR*)&addrRemote,&nAddrLen);
                                FD_SET(sNew,&fdsocket);
                                printf("接收到连接%s
    ",::inet_ntoa(addrRemote.sin_addr));
                            }else{
                                printf("too much connections!
    ");
                                continue;
                            }
                        }else{
                            char szText[256];
                            int nRecv = ::recv(fdsocket.fd_array[i],szText,strlen(szText),0);//可读
                            if(nRecv > 0){
                                szText[nRecv] = '
    ';
                                printf("接收到数据:%s",szText);
                            }else{ //连接关闭 重启或中断
                                ::closesocket(fdsocket.fd_array[i]);
                                FD_CLR(fdsocket.fd_array[i],&fdsocket);
                            }
                        }
                    }
                }
            }else{
                printf("Failed select()
    ");
                break;
            }
        }
        
        return 0;
    }

       

        2、WSAAsyncSelect模型

            WSAAsyncSelect模型允许应用程序以windows消息的形式接受到网络时间通知。 MFC的CSocket也是该模型。

            (为适应windows的消息驱动环境而设置的,现在许多对性能要求不高的网络应用程序都采用WSAASyncSelect模型)

        3、WSAEventSelect模型

        4、重叠(Overlapped)I/O模型

  • 相关阅读:
    关于线程的执行顺序
    常用正则表达式
    @JsonFormat与@DateTimeFormat注解的使用
    Mybatis中 #{} 和 ${} 的区别!
    [Redis]Spring Boot 中 Redis 的使用
    [WebSocket长连接]SpringBoot2.0集成WebSocket,实现后台向前端推送信息
    [springboot] 搭建项目及单元测试
    [AOP拦截 ]SpringBoot+Quartz Aop拦截Job类中的方法
    [vue折线图] 记录SpringBoot+Vue3.0折线图订单信息展示
    SpringBoot解决cors跨域问题
  • 原文地址:https://www.cnblogs.com/jackStudy/p/4372206.html
Copyright © 2011-2022 走看看