• C语言创建Socket实现双工通信


    实现简单的Socket通信案例(个人尝试)

    服务端代码(Server)

    #include <stdio.h>  
    #include <winsock2.h>  
    #pragma comment(lib,"ws2_32.lib")
    #define PORT 9999 
    
    int main()
    {
        WSADATA WSAData;
        SOCKET sock, msgsock;
        struct sockaddr_in ServerAddr;
    
        if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR)
        {
            ServerAddr.sin_family = AF_INET;
            ServerAddr.sin_port = htons(PORT);
            ServerAddr.sin_addr.s_addr = INADDR_ANY;
    
            sock = socket(AF_INET, SOCK_STREAM, 0);
            int BindRet = bind(sock, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr));
            int LinsRet = listen(sock, 10);
            printf("------------------------------------------------------------------------------------------
    ");
            printf("绑定状态: %d	 侦听状态: %d	 绑定端口: %d
    ", BindRet, LinsRet, ntohs(ServerAddr.sin_port));
            printf("------------------------------------------------------------------------------------------
    ");
        }
    
        while (1)
        {
            char buf[1024];
            msgsock = accept(sock, (LPSOCKADDR)0, (int *)0);
            memset(buf, 0, sizeof(buf));
            recv(msgsock, buf, 1024, 0);
            printf("客户IP: %s	 端口:%d	 数据:%s
    ", inet_ntoa(ServerAddr.sin_addr), htons(ServerAddr.sin_port),buf);
            if (!strcmp(buf, "Success"))
            {
                printf("客户端已就绪...
    ");
            }
            closesocket(msgsock);
        }
        closesocket(sock);
        WSACleanup();
        return 0;
    }
    View Code

    客户端代码(Client)

    #include <winsock2.h>
    #include <stdio.h>
    #pragma comment(lib,"ws2_32.lib")
    #define IP "127.0.0.1"
    #define PORT 9999
    
    //#ifdef _MSC_VER
    //#pragma comment( linker, "/subsystem:"windows" /entry:"mainCRTStartup"" )
    //#endif
    
    int main()
    {
        while (1)
        {
            WSADATA WSAData;
            SOCKET sock;
            struct sockaddr_in ClientAddr;
    
            if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR)
            {
                ClientAddr.sin_family = AF_INET;                //指Internet域
                ClientAddr.sin_port = htons(PORT);            //指定服务端所预留的端口
                ClientAddr.sin_addr.s_addr = inet_addr(IP);    //指定服务端所绑定的IP地址
    
                sock = socket(AF_INET, SOCK_STREAM, 0);
                int Ret = connect(sock, (LPSOCKADDR)&ClientAddr, sizeof(ClientAddr));
                if (Ret == 0)
                {
                    char Status[] = "Success";
                    int ServerRet = send(sock, Status, sizeof(Status), 0);
                    if (ServerRet != 0)
                    {
                        printf("发送给服务器Success状态成功..
    ");
                    }
                }
            }
            closesocket(sock);
            WSACleanup();
            Sleep(5000);
        }
        return 0;
    }
    View Code

    实现Socket单工通信案例

    服务端代码(Server)

    #include <stdio.h>  
    #include <winsock2.h>  
    #pragma comment(lib,"ws2_32.lib")    //把ws2_32.lib加到Link页的连接库  
    #define PORT 15001                    //通信的端口(指服务器端)
    #define ERROR 0  
    #define BUFFER_SIZE 1024            //注意:此Server端数据接收缓冲区 >= Client端数据发送缓冲区 ,否则造成缓冲区溢出
    /*
        服务端原理:
            1、服务器进程创建套接字
            2、将本地地址绑定到所创建的套接字上,以三元组{<通信协议>,<IP地址>,<端口号>}在网络上标识该套接字
            3、将套接字置入监听模式,并准备接受连接请求
    */
    int main()  
    {  
        WSADATA WSAData;  
        if(WSAStartup(MAKEWORD(2,0),&WSAData)==SOCKET_ERROR)  //启动winsock ,WSAStartup()函数对Winsock DLL进行初始化
        {  
            printf("Socket initialize fail!
    ");  
            exit(1);  
        }  
        SOCKET sock;                                        //服务进程创建套接字句柄(用于监听)
        if((sock=socket(AF_INET,SOCK_STREAM,0))==ERROR)        //调用socket()函数创建一个流套接字,参数(网络地址类型,套接字类型,网络协议)
        { 
            printf("Socket create!
    ");  
            WSACleanup();  
            exit(1);  
        }  
        struct sockaddr_in ServerAddr;            //sockaddr_in结构用来标识TCP/IP协议下的地址,可强制转换为sockaddr结构
        ServerAddr.sin_family=AF_INET;            //sin_family字段必须设为AF_INET,表示该Socket处于Internet域
        ServerAddr.sin_port=htons(PORT);        //sin_port字段用于指定服务端口,注意避免冲突
        ServerAddr.sin_addr.s_addr=INADDR_ANY;  //sin_addr字段用于把一个IP地址保存为一个4字节的数,无符号长整型,根据不同用法还可表示本地或远程IP地址
        if(bind(sock,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR)  //调用bind()函数将本地地址绑定到所创建的套接字上,以在网络上标识该套接字
        {   
            printf("Bind fail!
    ");  
            closesocket(sock);  
            WSACleanup();  
            exit(1);  
        }  
        printf("Server Socket Port:%d
    ",ntohs(ServerAddr.sin_port));  
        if(listen(sock,10)==SOCKET_ERROR)        //调用listen()函数将套接字置入监听模式并准备接受连接请求,参数(已捆绑未连接的套接字描述字,正在等待连接的最大队列长度)
        { 
            printf("Listen fail!
    ");  
            closesocket(sock);  
            WSACleanup();  
            exit(1);  
        }  
    
        SOCKET msgsock;            //创建一个新的套接字(用于接收accept函数的返回值,即表示已经接受的那个客户端的连接,进而接收Client发来的数据)
        char buf[BUFFER_SIZE];  //数据接收缓冲区
        while(1)  
        {  
            if((msgsock=accept(sock,(LPSOCKADDR)0,(int *)0))==INVALID_SOCKET)  //进入监听状态后,调用accept()函数接收客户端的连接请求,并把连接传给msgsock套接字,原sock套接字继续监听其他客户机连接请求
            {  
                printf("Accept fail!
    ");  
                continue;  
            }  
            memset(buf,0,sizeof(buf));                                            //初始化数据接收缓冲区
            recv(msgsock,buf,BUFFER_SIZE,0);                                    //接收客户端发送过来的数据  
            if(buf[0]=='e' && buf[1]=='x' && buf[2]=='i' && buf[3]=='t')        //"exit"命令,退出程序
            {  
                printf("The End.
    ");  
                break;  
            }
            printf("C:\Socket\Server>%s",buf);  
            closesocket(msgsock);  
        }  
    
        closesocket(sock); //关闭套接字  
        WSACleanup();       //终止对Winsock DLL的使用,并释放资源
        return 0;
    }   
    View Code

    客户端代码(Client)

    #include <winsock2.h>  
    #include <stdio.h>  
    #pragma comment(lib,"ws2_32.lib")    //把ws2_32.lib加到Link页的连接库  
    //#define IP "172.18.68.243"            //在两台计算机上测试,IP为Server端的IP地址  
    #define IP "127.0.0.1"                //在一台计算机上测试,IP为本地回送地址
    #define PORT 15001                    //注意:客户端设置通信的端口 = 服务端的端口
    #define BUFFER_SIZE 1024            //数据发送缓冲区大小
    
    int main()  
    {  
        char buf[BUFFER_SIZE];                                //buf数组存放客户端发送的消息  
        int inputLen;                                        //用于输入字符自增变量
        while(1)  
        {  
            printf("C:\Socket\Client>");  
            inputLen=0;  
            memset(buf,0,sizeof(buf));  
            while((buf[inputLen++]=getchar())!='
    ')        //输入以回车键为结束标识
            {
                ;
            }
            if(buf[0]=='e' && buf[1]=='x' && buf[2]=='i' && buf[3]=='t')  
            {  
                printf("The End.
    ");  
                break;   
            }  
    
            WSADATA WSAData;  
            if(WSAStartup(MAKEWORD(2,0),&WSAData)==SOCKET_ERROR)  //WSAStartup()函数对Winsock DLL进行初始化
            {  
                printf("Socket initialize fail!
    ");  
                continue;  
            }  
            SOCKET sock;                                            //客户端进程创建套接字
            if((sock=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR)  //创建流套接字(与服务端保持一致)
            {  
                printf("Socket create fail!
    ");  
                WSACleanup();  
                continue;  
            }  
    
            struct sockaddr_in ClientAddr;                //sockaddr_in结构用来标识TCP/IP协议下的地址,可强制转换为sockaddr结构
            ClientAddr.sin_family=AF_INET;                //指Internet域
            ClientAddr.sin_port=htons(PORT);            //指定服务端所预留的端口
            ClientAddr.sin_addr.s_addr=inet_addr(IP);    //指定服务端所绑定的IP地址
            if(connect(sock,(LPSOCKADDR)&ClientAddr,sizeof(ClientAddr))==SOCKET_ERROR)  //调用connect()函数,向服务器进程发出连接请求  
            { 
                printf("Connect fail!
    ");  
                closesocket(sock);  
                WSACleanup();  
                continue;  
            }  
            send(sock,buf,BUFFER_SIZE,0);                 //向服务器发送数据 
            closesocket(sock);                             //关闭套接字
            WSACleanup();                                //终止对Winsock DLL的使用,并释放资源,以备下一次使用
        }  
        return 0;
    }  
    View Code

    转载:https://blog.csdn.net/lynch0571

    实现Socket双工通信案例

    服务端代码(Server)

    #include <stdio.h>
    #include <Winsock2.h> //Socket的函数调用 
    #include <windows.h>
    
    #define BUF_SIZE 6400  //  缓冲区大小
    
    #pragma comment (lib, "ws2_32")     // 使用WINSOCK2.H时,则需要库文件WS2_32.LIB
    
    DWORD WINAPI Rcv(LPVOID lpParam)
    {
        SOCKET sClient = *(SOCKET*)lpParam;
        int retVal;
        char bufRecv[BUF_SIZE];
        memset(bufRecv, 0, sizeof(bufRecv));
        while (1)
        {
            retVal = recv(sClient, bufRecv, BUF_SIZE, 0);
            if (retVal == SOCKET_ERROR) {
                printf("recive faild!
    ");
                break;
            }
            else {
                printf("收到客户端消息:%s
    ", bufRecv);
            }
        }
        return 0;
    }
    
    DWORD WINAPI Snd(LPVOID lpParam)
    {
        SOCKET sClient = *(SOCKET*)lpParam;
        int retVal;
        char bufSend[BUF_SIZE];
        memset(bufSend, 0, sizeof(bufSend));
        while (1)
        {
            gets(bufSend);
            retVal = send(sClient, bufSend, strlen(bufSend) + sizeof(char), 0);
            if (retVal == SOCKET_ERROR) {
                printf("send faild!
    ");
                break;
            }
        }
        return 0;
    }
    
    
    int main(int argc, char* argv[])
    {
        // 初始化套接字动态库
        WSADATA wsaData;
        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
            printf("winsock load faild!
    ");
            return 1;
        }
    
        //  创建服务段套接字
        SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sServer == INVALID_SOCKET) {
            printf("socket faild!
    ");
            WSACleanup();
            return -1;
        }
    
        //  服务端地址
        sockaddr_in addrServ;
    
        addrServ.sin_family = AF_INET;
        addrServ.sin_port = htons(9999);
        addrServ.sin_addr.s_addr = htonl(INADDR_ANY);
    
        //  绑定套接字
        if (bind(sServer, (const struct sockaddr*)&addrServ, sizeof(addrServ)) == SOCKET_ERROR) {
            printf("bind faild!
    ");
            closesocket(sServer);
            WSACleanup();
            return -1;
        }
    
        printf("Server is On IP:[%s],port:[%d]
    ", inet_ntoa(addrServ.sin_addr), ntohs(addrServ.sin_port));
    
        //  监听套接字  数字表示最多能监听客户个数
        if (listen(sServer, 5) == SOCKET_ERROR) {
            printf("listen faild!
    ");
            closesocket(sServer);
            WSACleanup();
            return -1;
        }
    
        SOCKET sClient; //  客户端套接字
    
        sockaddr_in addrClient;
        int addrClientLen = sizeof(addrClient);
    
    
        sClient = accept(sServer, (sockaddr FAR*)&addrClient, &addrClientLen);
        if (sClient == INVALID_SOCKET) {
            printf("accept faild!
    ");
            closesocket(sServer);
            WSACleanup();
            return -1;
        }
        printf("accepted client IP:[%s],port:[%d]
    ", inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port));
    
        HANDLE hThread1, hThread2;
        DWORD dwThreadId1, dwThreadId2;
    
        hThread1 = ::CreateThread(NULL, NULL, Snd, (LPVOID*)&sClient, 0, &dwThreadId1);
        hThread2 = ::CreateThread(NULL, NULL, Rcv, (LPVOID*)&sClient, 0, &dwThreadId2);
    
        ::WaitForSingleObject(hThread1, INFINITE);
        ::WaitForSingleObject(hThread2, INFINITE);
        ::CloseHandle(hThread1);
        ::CloseHandle(hThread2);
    
        closesocket(sClient);
        WSACleanup(); // 资源释放
    
        return 0;
    }
    View Code

    客户端代码(Client)

    #include <stdio.h>
    #include <Winsock2.h> //Socket的函数调用 
    #include <windows.h>
    
    #define BUF_SIZE 6400
    
    #pragma comment (lib, "ws2_32")     // 使用WINSOCK2.H时,则需要库文件WS2_32.LIB
    
    DWORD WINAPI Rcv(LPVOID lpParam)
    {
        SOCKET sHost = *(SOCKET*)lpParam;
        int retVal;
        char bufRecv[BUF_SIZE];
        memset(bufRecv, 0, sizeof(bufRecv));
        while (1)
        {
            retVal = recv(sHost, bufRecv, BUF_SIZE, 0);
            if (retVal == SOCKET_ERROR) {
                printf("recive faild!
    ");
                break;
            }
            else {
                printf("收到服务器消息:%s
    ", bufRecv);
            }
        }
        return 0;
    }
    
    DWORD WINAPI Snd(LPVOID lpParam)
    {
        SOCKET sHost = *(SOCKET*)lpParam;
        int retVal;
        char bufSend[BUF_SIZE];
        memset(bufSend, 0, sizeof(bufSend));
        while (1)
        {
            gets(bufSend);
            retVal = send(sHost, bufSend, strlen(bufSend) + sizeof(char), 0);
            if (retVal == SOCKET_ERROR) {
                printf("send faild!
    ");
                break;
            }
        }
        return 0;
    }
    
    int main(int argc, char* argv[])
    {
        WSADATA wsaData;
        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
            printf("Winsock load faild!
    ");
            return 1;
        }
    
        //  服务器套接字
        SOCKET sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sHost == INVALID_SOCKET) {
            printf("socket faild!
    ");
            WSACleanup();
            return -1;
        }
    
        SOCKADDR_IN servAddr;
        servAddr.sin_family = AF_INET;
        //  注意   当把客户端程序发到别人的电脑时 此处IP需改为服务器所在电脑的IP
        servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
        servAddr.sin_port = htons(9999);
    
        //  连接服务器
        if (connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {
            printf("connect faild!
    ");
            closesocket(sHost);
            WSACleanup();
            return -1;
        }
        printf("连接到服务器 IP:[%s],port:[%d]
    ", inet_ntoa(servAddr.sin_addr), ntohs(servAddr.sin_port));
    
        HANDLE hThread1, hThread2;
        DWORD dwThreadId1, dwThreadId2;
    
        hThread1 = ::CreateThread(NULL, NULL, Snd, (LPVOID)&sHost, 0, &dwThreadId1);
        hThread2 = ::CreateThread(NULL, NULL, Rcv, (LPVOID)&sHost, 0, &dwThreadId2);
    
        ::WaitForSingleObject(hThread1, INFINITE);
        ::WaitForSingleObject(hThread2, INFINITE);
        ::CloseHandle(hThread1);
        ::CloseHandle(hThread2);
    
    
        closesocket(sHost);
        WSACleanup();
        return 0;
    }
    View Code

    转载:https://www.cnblogs.com/wuyepeng/

    实现文件传输

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    #include <WinSock2.h> 
    
    #define PORT 8087 
    #define SERVER_IP "127.0.0.1" 
    #define BUFFER_SIZE 1024 
    #define FILE_NAME_MAX_SIZE 512 
    #pragma comment(lib, "WS2_32") 
    
    int main()
    {
        // 声明并初始化一个服务端(本地)的地址结构 
        sockaddr_in server_addr;
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.S_un.S_addr = INADDR_ANY;
        server_addr.sin_port = htons(PORT);
    
        // 初始化socket dll 
        WSADATA wsaData;
        WORD socketVersion = MAKEWORD(2, 0);
        if (WSAStartup(socketVersion, &wsaData) != 0)
        {
            printf("Init socket dll error!");
            exit(1);
        }
    
        // 创建socket 
        SOCKET m_Socket = socket(AF_INET, SOCK_STREAM, 0);
        if (SOCKET_ERROR == m_Socket)
        {
            printf("Create Socket Error!");
            exit(1);
        }
    
        //绑定socket和服务端(本地)地址 
        if (SOCKET_ERROR == bind(m_Socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)))
        {
            printf("Server Bind Failed: %d", WSAGetLastError());
            exit(1);
        }
    
        //监听 
        if (SOCKET_ERROR == listen(m_Socket, 10))
        {
            printf("Server Listen Failed: %d", WSAGetLastError());
            exit(1);
        }
    
    
        while (1)
        {
            printf("Listening To Client...
    ");
    
            sockaddr_in client_addr;
            int client_addr_len = sizeof(client_addr);
    
            SOCKET m_New_Socket = accept(m_Socket, (sockaddr *)&client_addr, &client_addr_len);
            if (SOCKET_ERROR == m_New_Socket)
            {
                printf("Server Accept Failed: %d", WSAGetLastError());
                break;
            }
    
            char buffer[BUFFER_SIZE];
            memset(buffer, 0, BUFFER_SIZE);
            if (recv(m_New_Socket, buffer, BUFFER_SIZE, 0) < 0)
            {
                printf("Server Receive Data Failed!");
                break;
            }
    
            char file_name[FILE_NAME_MAX_SIZE + 1];
            memset(file_name, 0, FILE_NAME_MAX_SIZE + 1);
            strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
            printf("%s
    ", file_name);
    
            FILE * fp = fopen(file_name, "rb"); //windows下是"rb",表示打开一个只读的二进制文件 
            if (NULL == fp)
            {
                printf("File: %s Not Found
    ", file_name);
            }
            else
            {
                memset(buffer, 0, BUFFER_SIZE);
                int length = 0;
    
                while ((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
                {
                    if (send(m_New_Socket, buffer, length, 0) < 0)
                    {
                        printf("Send File: %s Failed
    ", file_name);
                        break;
                    }
                    memset(buffer, 0, BUFFER_SIZE);
                }
    
                fclose(fp);
                printf("File: %s Transfer Successful!
    ", file_name);
            }
            closesocket(m_New_Socket);
        }
    
        closesocket(m_Socket);
        //释放winsock库 
        WSACleanup();
        return 0;
    }
    View Code
    /*************************************************************************
    > File Name: Win_Client.c
    > Author: SongLee
    ************************************************************************/
    
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    #include <WinSock2.h> 
    
    #define PORT 8087 
    #define SERVER_IP "127.0.0.1" 
    #define BUFFER_SIZE 1024 
    #define FILE_NAME_MAX_SIZE 512 
    #pragma comment(lib, "WS2_32") 
    
    int main()
    {
        // 初始化socket dll 
        WSADATA wsaData;
        WORD socketVersion = MAKEWORD(2, 0);
        if (WSAStartup(socketVersion, &wsaData) != 0)
        {
            printf("Init socket dll error!");
            exit(1);
        }
    
        //创建socket 
        SOCKET c_Socket = socket(AF_INET, SOCK_STREAM, 0);
        if (SOCKET_ERROR == c_Socket)
        {
            printf("Create Socket Error!");
            system("pause");
            exit(1);
        }
    
        //指定服务端的地址 
        sockaddr_in server_addr;
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);
        server_addr.sin_port = htons(PORT);
    
        if (SOCKET_ERROR == connect(c_Socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)))
        {
            printf("Can Not Connect To Server IP!
    ");
            system("pause");
            exit(1);
        }
    
        //输入文件名 
        char file_name[FILE_NAME_MAX_SIZE + 1];
        memset(file_name, 0, FILE_NAME_MAX_SIZE + 1);
        printf("Please Input File Name On Server: ");
        scanf("%s", &file_name);
    
        char buffer[BUFFER_SIZE];
        memset(buffer, 0, BUFFER_SIZE);
        strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
    
        //向服务器发送文件名 
        if (send(c_Socket, buffer, BUFFER_SIZE, 0) < 0)
        {
            printf("Send File Name Failed
    ");
            system("pause");
            exit(1);
        }
    
        //打开文件,准备写入 
        FILE * fp = fopen(file_name, "wb"); //windows下是"wb",表示打开一个只写的二进制文件 
        if (NULL == fp)
        {
            printf("File: %s Can Not Open To Write
    ", file_name);
            system("pause");
            exit(1);
        }
        else
        {
            memset(buffer, 0, BUFFER_SIZE);
            int length = 0;
            while ((length = recv(c_Socket, buffer, BUFFER_SIZE, 0)) > 0)
            {
                if (fwrite(buffer, sizeof(char), length, fp) < length)
                {
                    printf("File: %s Write Failed
    ", file_name);
                    break;
                }
                memset(buffer, 0, BUFFER_SIZE);
            }
    
            printf("Receive File: %s From Server Successful!
    ", file_name);
        }
    
        fclose(fp);
        closesocket(c_Socket);
    
        //释放winsock库 
        WSACleanup();
    
        system("pause");
        return 0;
    }
    View Code

    转载:脚本之家

    使用select

    #include<stdlib.h>
    #include<WINSOCK2.H>
    #include <windows.h> 
    #include <process.h>  
    
    #include<iostream>
    #include<string>
    using namespace std;
    
    #define BUF_SIZE 64
    #pragma comment(lib,"WS2_32.lib")
    
    
    void recv(PVOID pt)
    {
        SOCKET  sHost = *((SOCKET *)pt);
    
        while (true)
        {
            char buf[BUF_SIZE];//清空接收数据的缓冲区
            memset(buf, 0, BUF_SIZE);
            int retVal = recv(sHost, buf, sizeof(buf), 0);
            if (SOCKET_ERROR == retVal)
            {
                int  err = WSAGetLastError();
                //无法立即完成非阻塞Socket上的操作
                if (err == WSAEWOULDBLOCK)
                {
                    Sleep(1000);
                    printf("
    waiting  reply!");
                    continue;
                }
                else if (err == WSAETIMEDOUT || err == WSAENETDOWN || err == WSAECONNRESET)//已建立连接
                {
                    printf("
    recv failed!");
                    closesocket(sHost);
                    WSACleanup();
                    return;
                }
    
            }
    
            Sleep(100);
    
            printf("
    %s", buf);
            //break;
        }
    }
    
    
    int main()
    {
        WSADATA wsd;
        SOCKET sHost;
        SOCKADDR_IN servAddr;//服务器地址
        int retVal;//调用Socket函数的返回值
        char buf[BUF_SIZE];
        //初始化Socket环境
        if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
        {
            printf("WSAStartup failed!
    ");
            return -1;
        }
        sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        //设置服务器Socket地址
        servAddr.sin_family = AF_INET;
        servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
        //在实际应用中,建议将服务器的IP地址和端口号保存在配置文件中
        servAddr.sin_port = htons(6000);
        //计算地址的长度
        int sServerAddlen = sizeof(servAddr);
    
    
    
        //调用ioctlsocket()将其设置为非阻塞模式
        int iMode = 1;
        retVal = ioctlsocket(sHost, FIONBIO, (u_long FAR*)&iMode);
    
    
        if (retVal == SOCKET_ERROR)
        {
            printf("ioctlsocket failed!");
            WSACleanup();
            return -1;
        }
    
    
        //循环等待
        while (true)
        {
            //连接到服务器
            retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
            if (SOCKET_ERROR == retVal)
            {
                int err = WSAGetLastError();
                //无法立即完成非阻塞Socket上的操作
                if (err == WSAEWOULDBLOCK || err == WSAEINVAL)
                {
                    Sleep(1);
                    printf("check  connect!
    ");
                    continue;
                }
                else if (err == WSAEISCONN)//已建立连接
                {
                    break;
                }
                else
                {
                    printf("connection failed!
    ");
                    closesocket(sHost);
                    WSACleanup();
                    return -1;
                }
            }
        }
    
    
        unsigned long     threadId = _beginthread(recv, 0, &sHost);//启动一个线程接收数据的线程   
    
    
    
        while (true)
        {
            //向服务器发送字符串,并显示反馈信息
            printf("input a string to send:
    ");
            std::string str;
            //接收输入的数据
            std::cin >> str;
            //将用户输入的数据复制到buf中
            ZeroMemory(buf, BUF_SIZE);
            strcpy(buf, str.c_str());
            if (strcmp(buf, "quit") == 0)
            {
                printf("quit!
    ");
                break;
            }
    
            while (true)
            {
                retVal = send(sHost, buf, strlen(buf), 0);
                if (SOCKET_ERROR == retVal)
                {
                    int err = WSAGetLastError();
                    if (err == WSAEWOULDBLOCK)
                    {
                        //无法立即完成非阻塞Socket上的操作
                        Sleep(5);
                        continue;
                    }
    
                    else
                    {
                        printf("send failed!
    ");
                        closesocket(sHost);
                        WSACleanup();
                        return -1;
                    }
                }
                break;
            }
    
    
        }
    
        return 0;
    }
    View Code
    #include <WinSock2.h>  
    #include <Windows.h>  
    #include <MSWSock.h>  
    #include <stdio.h>  
    #include <map>  
    using namespace std;
    
    
    #pragma comment(lib,"Ws2_32.lib")  
    #pragma comment(lib,"Mswsock.lib")  
    
    
    int main()
    {
        WSAData wsaData;
        if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData))
        {
            printf("初始化失败!%d
    ", WSAGetLastError());
            Sleep(5000);
            return -1;
        }
    
        USHORT nport = 6000;
        SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
        u_long ul = 1;
        ioctlsocket(sListen, FIONBIO, &ul);
    
        sockaddr_in sin;
        sin.sin_family = AF_INET;
        sin.sin_port = htons(nport);
        sin.sin_addr.S_un.S_addr = ADDR_ANY;
    
    
        if (SOCKET_ERROR == bind(sListen, (sockaddr*)&sin, sizeof(sin)))
        {
            printf("bind failed!%d
    ", WSAGetLastError());
            Sleep(5000);
            return -1;
        }
    
    
        listen(sListen, 5);
    
    
        //1)初始化一个套接字集合fdSocket,并将监听套接字放入  
        fd_set socketSet;
        FD_ZERO(&socketSet);
        FD_SET(sListen, &socketSet);
    
        TIMEVAL time = { 1, 0 };
        char buf[4096];
    
    
        fd_set    readSet;
        FD_ZERO(&readSet);
    
        fd_set    writeSet;
        FD_ZERO(&readSet);
    
    
        while (true)
        {
            //2)将fdSocket的一个拷贝fdRead传给select函数  
            readSet = socketSet;
            writeSet = socketSet;
    
            //同时检查套接字的可读可写性。
            int   nRetAll = select(0, &readSet, &writeSet, NULL, NULL/*&time*/);//若不设置超时则select为阻塞  
            if (nRetAll >0)   //-1
            {
                //是否存在客户端的连接请求。  
                if (FD_ISSET(sListen, &readSet))//在readset中会返回已经调用过listen的套接字。  
                {
    
                    if (socketSet.fd_count < FD_SETSIZE)
                    {
                        sockaddr_in addrRemote;
                        int nAddrLen = sizeof(addrRemote);
                        SOCKET sClient = accept(sListen, (sockaddr*)&addrRemote, &nAddrLen);
                        if (sClient != INVALID_SOCKET)
                        {
                            FD_SET(sClient, &socketSet);
                            printf("
    接收到连接:(%s)", inet_ntoa(addrRemote.sin_addr));
                        }
                    }
                    else
                    {
                        printf("连接数量已达上限!
    ");
                        continue;
                    }
                }
    
    
                for (int i = 0; i<socketSet.fd_count; i++)
                {
                    if (FD_ISSET(socketSet.fd_array[i], &readSet))
                    {
                        //调用recv,接收数据。 
                        int nRecv = recv(socketSet.fd_array[i], buf, 4096, 0);
                        if (nRecv > 0)
                        {
                            buf[nRecv] = 0;
                            printf("
    recv  %d :  %s", socketSet.fd_array[i], buf);
                        }
                    }
    
                    if (FD_ISSET(socketSet.fd_array[i], &writeSet))
                    {
    
                        //调用send,发送数据。
                        char buf[] = "hello!";
                        int nRet = send(socketSet.fd_array[i], buf, strlen(buf) + 1, 0);
                        if (nRet <= 0)
                        {
                            if (GetLastError() == WSAEWOULDBLOCK)
                            {
                                //do nothing  
                            }
                            else
                            {
                                closesocket(socketSet.fd_array[i]);
                                FD_CLR(socketSet.fd_array[i], &socketSet);
                            }
                        }
                        else
                        {
                            printf("
    send  hello!");
                        }
                    }
                }
    
            }
            else if (nRetAll == 0)
            {
                printf("time out!
    ");
            }
            else
            {
                printf("select error!%d
    ", WSAGetLastError());
                Sleep(5000);
                break;
            }
    
            Sleep(1000);
    
        }
        closesocket(sListen);
        WSACleanup();
    }
    View Code
  • 相关阅读:
    HDU 3537
    POJ 1175
    POJ 1021 人品题
    POJ 2068
    POJ 2608
    POJ 2960
    poj 1635
    ustc 1117
    ural 1468
    数字游戏
  • 原文地址:https://www.cnblogs.com/LyShark/p/9158656.html
Copyright © 2020-2023  润新知