8_1——非阻塞模式(ioctlsocket)

//Server.cpp 
#include <stdio.h> 
#include <winsock2.h>             //winsock.h (2种套接字版本) 
#pragma comment(lib,"ws2_32.lib") //wsock32.lib 
 
#define MAXSIZE 100 // 
 
int main() 

    // 
    int retVal; 
 
    char buf[MAXSIZE]; 
 
    //初始化套接字库 
    WORD wVersionRequest; 
    WSADATA wsadata; 
 
    wVersionRequest=MAKEWORD(2,2); 
 
    retVal=WSAStartup(wVersionRequest,&wsadata); 
    if(retVal == SOCKET_ERROR) 
    { 
        printf("WSAStartup failed!"); 
 
        return -1; 
    } 
 
    //创建套接字 
    SOCKET sServer; 
    sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
    if(sServer == INVALID_SOCKET) 
    { 
        printf("socket failed!"); 
 
        WSACleanup(); 
        return -1; //每次检测到失败后,即需要返回 
    } 
 
    //设置为非阻塞模式 
    int imode=1; 
    retVal=ioctlsocket(sServer,FIONBIO,(u_long *)&imode); 
    if(retVal == SOCKET_ERROR) 
    { 
        printf("ioctlsocket failed!"); 
 
        closesocket(sServer); 
        WSACleanup(); 
        return -1; 
    } 
 
    //绑定套接字并将其设置为监听状态 
    SOCKADDR_IN addrServ; 
    addrServ.sin_family=AF_INET; 
    addrServ.sin_port  =htons(5000); 
    addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102"); 
 
    retVal=bind(sServer,(SOCKADDR *)&addrServ,sizeof(addrServ)); //绑定套接字到某一个具体的服务器 
    if(retVal == SOCKET_ERROR) 
    { 
        printf("bind failed!"); 
 
        closesocket(sServer); 
        WSACleanup(); 
        return -1; 
    } 
 
    retVal=listen(sServer,1); //第二个参数,表示最大连接数目 
    if(retVal == SOCKET_ERROR) 
    { 
        printf("listen failed!"); 
 
        closesocket(sServer); 
        WSACleanup(); 
        return -1; 
    } 
 
 
    //接受连接 
    sockaddr_in addrClient; //定义一个临时地址,用于接受连接(注意:某个客户端由Client.cpp确定) 
    int len=sizeof(sockaddr_in); 
 
    SOCKET sClient; 
    int errcode; 
 
    while(true) 
    { 
        sClient=accept(sServer,(sockaddr *)&addrClient,&len); 
        if(sClient == INVALID_SOCKET) 
        { 
            errcode=WSAGetLastError(); 
            if(errcode == WSAEWOULDBLOCK)  //表示没有客户端发起连接,继续循环 
            { 
                Sleep(100); 
                continue; 
            } 
            else
            { 
                printf("accept failed!"); 
 
                closesocket(sServer); //连接失败,关闭服务器套接字并释放套接字库 
                WSACleanup(); // 
                return -1; 
            } 
        } 
 
        break; // 
    } 
 
    //接收数据 
    while(true) 
    { 
        retVal=recv(sClient,buf,strlen(buf),0); 
        if(retVal == SOCKET_ERROR) 
        { 
            errcode=WSAGetLastError(); //这个变量errcode没有重复定义吗? 
            if(errcode == WSAEWOULDBLOCK)  // 
            { 
                Sleep(100); 
                continue; 
            } 
            else
            { 
                if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN) 
                { 
                    closesocket(sClient); 
                    closesocket(sServer); 
                    WSACleanup(); 
                    return -1; 
                } 
            } 
        } 
 
        if(buf == "quit") //如果接收数据为"quit",则发送回显"quit" 
        { 
            retVal=send(sClient,buf,strlen(buf),0); 
            break; 
        } 
        else
        { 
            //发送数据 
            while(true) 
            { 
                retVal=send(sClient,buf,strlen(buf),0); //a.回显接收数据;b.第四个参数:0? 
                if(retVal == SOCKET_ERROR)  //错误处理 
                { 
                    errcode=WSAGetLastError(); 
                    if(errcode == WSAEWOULDBLOCK)  // 
                    { 
                        Sleep(100); 
                        continue; 
                    } 
                    else
                    { 
                        closesocket(sClient); 
                        closesocket(sServer); 
                        WSACleanup(); 
                        return -1; 
 
                    } 
                } 
 
                break; //如果发送数据成功,则退出循环 
            } 
 
        } 
    } 
 
}


//Client.cpp 
#include <stdio.h> 
#include <WinSock2.h> //winsock.h 
#pragma comment(lib,"ws2_32.lib"); //wsock32.lib 
 
#include <iostream> 
using namespace std; 
 
#include <string.h> //strcpy函数 
 
#define MAXSIZE 100 // 
 
int main() 

    // 
    int retVal; 
 
    char buf[MAXSIZE]; 
 
    //初始化套接字库 
    WORD wVersionRequest; 
    WSADATA wsadata; 
 
    wVersionRequest=MAKEWORD(2,2); 
 
    retVal=WSAStartup(wVersionRequest,&wsadata); 
    if(retVal == SOCKET_ERROR) 
    { 
        printf("WSAStartup failed!"); 
 
        return -1; 
    } 
 
    //创建套接字 
    SOCKET sClient; 
    sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
    if(sClient == INVALID_SOCKET) 
    { 
        printf("socket failed!"); 
 
        WSACleanup(); 
        return -1; //每次检测到失败后,即需要返回 
    } 
 
    //设置为非阻塞模式 
    int imode=1; 
    retVal=ioctlsocket(sClient,FIONBIO,(u_long *)&imode); 
    if(retVal == SOCKET_ERROR) 
    { 
        printf("ioctlsocket failed!"); 
 
        closesocket(sClient); 
        WSACleanup(); 
        return -1; 
    } 
 
 
    //发起连接 
    sockaddr_in addrServ; 
    addrServ.sin_family=AF_INET; //表示使用的是,TCP/IP地址家族 
    addrServ.sin_port  =htons(5000); //为什么要使用htons宏? 
    addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102"); 
 
    int len=sizeof(sockaddr_in); //sizeof只是一个运算符,不是函数 
 
    while(true) 
    { 
        retVal=connect(sClient,(sockaddr *)&addrServ,len); //连接到某一个具体的服务器 
        if(retVal == INVALID_SOCKET) 
        { 
            int errcode=WSAGetLastError(); 
            if(errcode==WSAEWOULDBLOCK || errcode==WSAEINVAL)  //表示服务器端未准备好,继续循环 
            { 
                Sleep(100); 
                continue; 
            } 
            else
            { 
                if(errcode == WSAEISCONN) //连接成功,则退出 
                { 
                    break;  
                } 
                else                      //否则连接失败,关闭客户端套接字并释放套接字库 
                { 
                    printf("connect failed!"); 
 
                    closesocket(sClient);  
                    WSACleanup(); // 
                    return -1; 
                } 
             } 
        } 
 
    } 
 
    //发送数据 
    while(true) 
    { 
        // 
        //scanf(buf); 
        //cin>>buf; 
 
        strcpy(buf,"Hello TCP!"); 
 
        retVal=send(sClient,buf,strlen(buf),0); //a.回显接收数据;b.第四个参数:0? 
        if(retVal == SOCKET_ERROR)  //错误处理 
        { 
            int errcode=WSAGetLastError(); 
            if(errcode == WSAEWOULDBLOCK)  // 
            { 
                Sleep(100); 
                continue; 
            } 
            else
            { 
                printf("send failed!"); 
 
                closesocket(sClient); 
                //closesocket(sServer); 
                WSACleanup(); 
                return -1; 
 
            } 
        } 
 
        break; //如果发送数据成功,则退出循环 
    } 
 
    //接收数据 
    while(true) 
    { 
        retVal=recv(sClient,buf,strlen(buf),0); 
        if(retVal == SOCKET_ERROR) 
        { 
            int errcode=WSAGetLastError(); //这个变量errcode没有重复定义吗? 
            if(errcode == WSAEWOULDBLOCK)  // 
            { 
                Sleep(100); 
                continue; 
            } 
            else
            { 
                if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN) 
                { 
                    printf("recv failed!"); 
 
                    closesocket(sClient); 
                    //closesocket(sServer); 
                    WSACleanup(); 
                    return -1; 
                } 
            } 
        } 
 
        break; 
    } 
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值