winsock select 学习代码(2)
2020-12-13 02:20
                         标签:c   class   blog   code   a   tar    之前文章的改进版 服务器仅仅接受客户端发送的字符串并显示 客户端可以调节发送数目 但是不能超过64         winsock select 学习代码(2),搜素材,soscw.com winsock select 学习代码(2) 标签:c   class   blog   code   a   tar    原文地址:http://www.cnblogs.com/itdef/p/3763305.html
 
       
    
       
// SelectServer.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include #include #pragma comment(lib,"ws2_32")#define SOCKET_MAXCNT   64#define THREAD_NUM      2 #define CONNECT_PORT    8773    #define CONNECT_ADDR    "127.0.0.1"#define DATA_BUF_SZIE   8192typedef struct 
_SOCKET_INFORMATION {
    CHAR Buffer[DATA_BUF_SZIE];
    WSABUF DataBuf;
    SOCKET Socket;
    OVERLAPPED Overlapped;
} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;DWORD   totalSockets = 0;LPSOCKET_INFORMATION SocketArray[FD_SETSIZE];BOOL CreateSocketInformation(SOCKET s){    LPSOCKET_INFORMATION SI;
    printf("Accepted socket number %d\n", s);
    if 
((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,
        sizeof(SOCKET_INFORMATION))) == NULL)
    {
        printf("GlobalAlloc() failed with error %d\n", GetLastError());
        return 
FALSE;
    }
    // Prepare SocketInfo structure for use.
    SI->Socket = s;
    SocketArray[totalSockets] = SI;
    totalSockets++;
    return(TRUE);
}void 
FreeSocketInformation(DWORD Index)
{    LPSOCKET_INFORMATION SI = SocketArray[Index];
    DWORD i;
    closesocket(SI->Socket);
    printf("Closing socket number %d\n", SI->Socket);
    GlobalFree(SI);
    // Squash the socket array
    for 
(i = Index; i 
    {
        SocketArray[i] = SocketArray[i + 1];
    }
    totalSockets--;
}int 
_tmain(int 
argc, _TCHAR* argv[])
{    WSAData wsaData;
    SOCKADDR_IN InternetAddr = {0};
    FD_SET ReadSet;
    DWORD   i = 0;
    DWORD   total = 0;
    DWORD   Flags;
    DWORD   RecvBytes = 0;
    SOCKET  listenSock = INVALID_SOCKET;
    SOCKET  acceptSock = INVALID_SOCKET;
    if( WSAStartup(MAKEWORD(2,2),&wsaData) != 0 )
    {
        printf("WSAStartup error,exit\n");
        goto 
SOCKET_CLEAN;
    }
    listenSock = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,
        WSA_FLAG_OVERLAPPED);
    if(listenSock == INVALID_SOCKET)
    {
        printf("WSASocket error \n");
        goto 
SOCKET_CLEAN;
    }
    InternetAddr.sin_family = AF_INET;
    InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    InternetAddr.sin_port = htons(CONNECT_PORT);
    if 
(bind(listenSock, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr))
        == SOCKET_ERROR)
    {
        printf("bind() failed with error %d\n", WSAGetLastError());
        goto 
SOCKET_CLEAN;
    }
    if 
(listen(listenSock, 5))
    {
        printf("listen() failed with error %d\n", WSAGetLastError());
        goto 
SOCKET_CLEAN;
    }
    // Change the socket mode on the listening socket from blocking to
    // non-block so the application will not block waiting for requests.
    ULONG NonBlock = 1;
    if 
(ioctlsocket(listenSock, FIONBIO, &NonBlock) == SOCKET_ERROR)
    {
        printf("ioctlsocket() failed with error %d\n", WSAGetLastError());
        goto 
SOCKET_CLEAN;
    }
    while(1)
    {
        FD_ZERO(&ReadSet);  
        FD_SET(listenSock, &ReadSet);
        for 
(i = 0; i 
        {
            FD_SET(SocketArray[i]->Socket, &ReadSet);
        }
        total = select(0,&ReadSet,NULL,NULL,NULL);
        if(total == SOCKET_ERROR)
        {
            printf("select() failed with error %d\n", WSAGetLastError());
            goto 
SOCKET_CLEAN;
        }
        if(FD_ISSET(listenSock,&ReadSet))
        {
            total--;
            acceptSock = accept(listenSock,NULL,NULL);
            if(acceptSock == INVALID_SOCKET)
            {
                if 
(WSAGetLastError() != WSAEWOULDBLOCK)
                {
                    printf("accept() failed with error %d\n", WSAGetLastError());
                    goto 
SOCKET_CLEAN;
                }
            }else
            {
                NonBlock = 1;
                int 
ret = ioctlsocket(acceptSock,FIONBIO, &NonBlock);
                if(ret == SOCKET_ERROR)
                {
                    printf("ioctlsocket() failed with error %d\n", WSAGetLastError());
                    goto 
SOCKET_CLEAN;
                }
                if 
(CreateSocketInformation(acceptSock) == FALSE)
                    goto 
SOCKET_CLEAN;
            }
        }
        for 
(i = 0; total > 0 && i 
        {
            LPSOCKET_INFORMATION SocketInfo = SocketArray[i];
            SocketInfo->DataBuf.buf = SocketInfo->Buffer;
            SocketInfo->DataBuf.len = DATA_BUF_SZIE;
            if(FD_ISSET(SocketInfo->Socket,&ReadSet))
            {
                total--;
                Flags = 0;
                ZeroMemory(SocketInfo->Buffer,DATA_BUF_SZIE);
                if 
(WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes,
                    &Flags, NULL, NULL) == SOCKET_ERROR)
                {
                    if 
(WSAGetLastError() != WSAEWOULDBLOCK)
                    {
                        printf("WSARecv() failed with error %d\n", WSAGetLastError());
                        FreeSocketInformation(i);
                    }
                    continue;
                }else
                {
                    printf(SocketInfo->Buffer);
                    if(RecvBytes == 0)
                    {
                        FreeSocketInformation(i);
                        continue;
                    }
                }
            }
        }
    }
SOCKET_CLEAN:    if(listenSock != INVALID_SOCKET)
    {
        closesocket(listenSock);
        listenSock = INVALID_SOCKET;
    }
    if(acceptSock != INVALID_SOCKET)
    {
        closesocket(acceptSock);
        acceptSock = INVALID_SOCKET;
    }
    WSACleanup();
    return 
0;
}
 
       
    
       
// CommonClient.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include #include #pragma comment(lib,"ws2_32")#define SOCKET_MAXCNT   64#define THREAD_NUM      22 #define CONNECT_PORT    8773    #define CONNECT_ADDR    "127.0.0.1"DWORD WINAPI SocketFunc(LPVOID pM) {    char 
buf[512] = {0};  
    SOCKET  sock;
    int 
result;
    struct 
sockaddr_in cli_addr;
    int 
num = *(int*)pM;
    sock = socket(AF_INET,SOCK_STREAM,0);
    cli_addr.sin_family = AF_INET;
    cli_addr.sin_port = htons(CONNECT_PORT);
    cli_addr.sin_addr.s_addr = inet_addr(CONNECT_ADDR);
    result = connect(sock,(struct 
sockaddr*)&cli_addr,sizeof(cli_addr));
    if(result == SOCKET_ERROR)
    {
        printf("%d thread: connect error\n",num);
        exit(1);
    }
    while(1)
    {
        sprintf(buf,"%d thread: %s",num,"hello world!\n");
        printf(buf);
        result = send(sock,buf,100,0);
        if(result == SOCKET_ERROR)
        {
            printf("%d error \n",num);
            return 
0;
        }
        Sleep(3000);
    }
    exit(1);
    return 
0;
}int 
_tmain(int 
argc, _TCHAR* argv[])
{    int 
num[SOCKET_MAXCNT] = {0};
    WSADATA wsa_data;
    WSAStartup(WINSOCK_VERSION,&wsa_data);
    // 初始化数组 传递给线程  区别各个线程号
    for(int 
i = 0 ;i 
    {
        num[i] = i;
    }
    for(int 
i = 0; i 
    {
        HANDLE hThread = CreateThread(NULL,0,SocketFunc,&num[i],0,NULL);
        if(hThread != NULL)
        {
            CloseHandle(hThread);
        }
    }
    while(1)
    {
        Sleep(100000);
    }
    return 
0;
}