windows tcp服务器代码,多线程+select

#include "stdafx.h"
#pragma comment(lib, "Ws2_32.lib")

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#include <process.h>

#define  PORT 5038
#define  CONCOUNTS 5
#define  COMLENGTH 256
typedef struct crossThread 
{
    SOCKET confd[CONCOUNTS]; //no lock.
    HANDLE conEvent;
}crossThread;
void initSocket();
unsigned int __stdcall ThreadFunSendData(PVOID pM); //is better than CreateThread
unsigned int __stdcall ThreadFunRecvData(PVOID pM);
unsigned int __stdcall ThreadFunKeepConn(PVOID pM);
int _tmain(int argc, _TCHAR* argv[])
{

    initSocket(); //windows special setting

    int i=0;
    const int THREAD_NUM = 3;  
    HANDLE handle[THREAD_NUM];
    crossThread pM;
    for(i = 0; i< CONCOUNTS;i++)
    {
        pM.confd[i] = 0;
    }
    pM.conEvent = CreateEvent(NULL,FALSE,FALSE,NULL);

    handle[0] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunSendData, (PVOID)&pM, 0, NULL);
    handle[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunRecvData, (PVOID)&pM, 0, NULL);
    handle[2] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunKeepConn, (PVOID)&pM, 0, NULL);  
    WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);

    for(i = 0; i< THREAD_NUM;i++)
        CloseHandle(handle[i]);
    CloseHandle(pM.conEvent);
    WSACleanup();
    system("PAUSE");
}

void initSocket() //for winsocket dll.
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MAKEWORD(2, 2);
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) {
        /* Tell the user that we could not find a usable */
        /* Winsock DLL.                                  */
        printf("WSAStartup failed with error: %d\n", err);
        return;
    }

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
        /* Tell the user that we could not find a usable */
        /* WinSock DLL.                                  */
        printf("Could not find a usable version of Winsock.dll\n");
        WSACleanup();
        return;
    }
    else
        printf("The Winsock 2.2 dll was found okay\n");
}
unsigned int __stdcall ThreadFunSendData(PVOID _pM)  
{
    crossThread* pM = (crossThread*)_pM;
    char commandString[COMLENGTH];
    int stringLength=0;
    int sendResult =0 ,i = 0;
    while(1)
    {
        gets(commandString);
        stringLength =strlen(commandString);
        if (stringLength >0)
        {
            for(i=0;i<CONCOUNTS;i++) //broadcast to every clients
            {
                sendResult =send(pM->confd[i],commandString,stringLength,0);  
            }
        }
    }   
    return 0;
}

unsigned int __stdcall ThreadFunRecvData(PVOID _pM)  
{
    crossThread* pM = (crossThread*)_pM;
    char commandString[COMLENGTH] ={0};
    int recvLength=0,i =0;
    /////////////////////////////////////
    FD_SET readSet;
    FD_ZERO(&readSet);
    //////////////////////////////////
    while(1)
    {
        WaitForSingleObject(pM->conEvent,INFINITE);

        for(i=0; i<CONCOUNTS;i++)
        {
            if (pM->confd[i] >0)
            {
                FD_SET(pM->confd[i],&readSet);
            }
        }
        int ret=select(0,&readSet,NULL,NULL,NULL); //wait for different client msg


        for(i=0; i<CONCOUNTS;i++)
        {
            if(FD_ISSET(pM->confd[i],&readSet))  
            {
                recvLength =recv(pM->confd[i],commandString,COMLENGTH,0);
                if (recvLength >0)
                {
                    printf("recv:%s\n",commandString);
                    memset(commandString,0,COMLENGTH);
                    SetEvent(pM->conEvent);
                }
            }
        }


    }
}
unsigned int __stdcall ThreadFunKeepConn(PVOID _pM)  
{
    crossThread* pM = (crossThread*)_pM;
    int connId =0;
    SOCKADDR_IN  client;
    socklen_t  addrlen;
    addrlen =sizeof(client);

    SOCKET sockSrv;
    SOCKADDR_IN  addrServ;

    sockSrv = socket(AF_INET, SOCK_STREAM, 0);

    int opt =SO_REUSEADDR;
    setsockopt(sockSrv,SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));  
    memset(&addrServ,0,sizeof(addrServ));  
    addrServ.sin_family=AF_INET;  
    addrServ.sin_port=htons(PORT);  
    addrServ.sin_addr.S_un.S_addr= htonl (INADDR_ANY);

    bind(sockSrv, (struct sockaddr *)&addrServ, sizeof(addrServ));
    listen(sockSrv,8);

    while(1)
    {
        pM->confd[connId] = accept(sockSrv,(struct sockaddr*)&client,&addrlen);//maybe use select is better.
        SetEvent(pM->conEvent);
        connId=(connId+1)%CONCOUNTS;
    }
    for (connId = 0 ;connId< CONCOUNTS;connId++)
    {
        closesocket(pM->confd[connId]);
    }
    closesocket(sockSrv);
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值