网络编程:select模型的简单实例

来源:互联网 发布:经济数据公布时间 编辑:程序博客网 时间:2024/05/20 18:45
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include "QtCore/QCoreApplication"
#include "Qt/qstring.h"
#include "Qt/qstringlist.h"
#include <cstdlib>
#define FD_SETSIZE 1024
#pragma comment(lib, "WS2_32")
#include <Windows.h>
using namespace std;  
#pragma comment(linker, "/subsystem:\"CONSOLE\" /entry:\"WinMainCRTStartup\"")

int main(int argc, char** argv)  
{      
    QCoreApplication app(argc, argv);
    string confName = ".\\conf.ini";
    WORD wVersionRequested;  
    WSADATA wsaData;       
    wVersionRequested = MAKEWORD(1, 1);  
    int err = WSAStartup( wVersionRequested, &wsaData );  
    if ( err != 0 ) {  
        return -1;          
    }  
    if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) {          
        WSACleanup( );  
        return -1;   
    }  
    SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);  
    if (sockSrv == INVALID_SOCKET)
    {
        printf("socket() called failed\n");
        return 0;
    }
    SOCKADDR_IN addrSrv;  
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    addrSrv.sin_family = AF_INET;  
    int socket_port = GetPrivateProfileIntA("Main", "Socket_port", -1, confName.c_str());
    addrSrv.sin_port = htons(socket_port);  
    if (bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) == SOCKET_ERROR)
    {
        printf("bind() called failed\n");
        return 0;
    }
    if (listen(sockSrv, 10) == SOCKET_ERROR)
    {
        printf("listen() called failed\n");
        return 0;
    }             
    int len = sizeof(SOCKADDR);    
    printf("等待客户端连接\n");
    ULONG NonBlock = 1;   
    if(ioctlsocket(sockSrv, FIONBIO, &NonBlock) == SOCKET_ERROR)   
    {   
        printf("ioctlsocket() failed with error %d\n", WSAGetLastError());
        return -1;   
    }     
    struct timeval timeout={2,0};   
    fd_set fdSocket;
    fd_set fdRead;
    FD_ZERO(&fdSocket);
    FD_SET(sockSrv, &fdSocket);

    while (1)
    {    
        FD_ZERO(&fdRead);
        fdRead = fdSocket;
        int nRet = select(0,&fdRead,(fd_set*) 0,(fd_set*) 0,&timeout);         
        if(nRet>0)
        {
            for(int i=0; i<(int)fdSocket.fd_count; i++)
            {
                if(FD_ISSET(fdSocket.fd_array[i], &fdRead))
                {
                    if(fdSocket.fd_array[i] == sockSrv)         
                    {
                        if(fdSocket.fd_count < FD_SETSIZE)
                        {  
                            sockaddr_in addrRemote;
                            int nAddrLen = sizeof(addrRemote);
                            SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrRemote, &nAddrLen);
                            if (INVALID_SOCKET == sockConn)
                            {
                                printf("accept() called failed\n");
                                continue;
                            }
                            FD_SET(sockConn, &fdSocket);
                            printf("接收到连接:%s\n", ::inet_ntoa(addrRemote.sin_addr));
                        }
                        else
                        {
                            printf(" Too much connections! \n");
                            continue;
                        }
                    }
                    else
                    {    
                        char recvBuf[8];                       
                        int ret = recv(fdSocket.fd_array[i], recvBuf, 8, 0);  
                        if (ret <= 0)
                        {     
                             printf("ret=%d,客户端断开\n", ret);
                             closesocket(fdSocket.fd_array[i]);
                             FD_CLR(fdSocket.fd_array[i], &fdSocket);                           
                        }        
                        else
                        {    
                            char temp[3];
                            memcpy(temp, recvBuf+2, 2);
                            temp[2] = 0;  
                            QString taskID;
                            if (strncmp(temp, "01", 2) == 0)//创建任务
                            {
                                int length;
                                char contentLen[4];
                                memcpy(contentLen, recvBuf+4, 4);
                                sscanf(contentLen, "%d", &length);
                                char* str = new char[length+1];
                                int size = 0;
                                int ret;
                                while(1)
                                {
                                    ret = recv(fdSocket.fd_array[i], str+size, length-size, 0);
                                    if (ret > 0)
                                    {
                                        size += ret;
                                        if (size == length)
                                        {
                                            break;
                                        }
                                    }                              
                                }
                                str[length] = 0;
                                printf("服务器收到创建消息:%s\n", str);
                                Sleep(1000);//模拟解析处理
                                QString content = str;
                                taskID = content.split("|").at(0);
                                //响应创建
                                int port = GetPrivateProfileIntA("Main", "port", -1, confName.c_str());
                                QString portTo = QString::number(port);
                                QString res = "010000060|";
                                res += portTo;
                                char data[14];
                                memcpy(data, res.toStdString().c_str(), 14);
                                int r = send(fdSocket.fd_array[i], data, 14, 0);    
                                printf("服务器响应创建消息:%s\n", res.toStdString().c_str());
                                Sleep(1000);//模拟视频分析
                                //发送停止消息
                                int stopLen = taskID.size();
                                char idLen[4];
                                sprintf(idLen, "%04d", stopLen);
                                res = "0102";   
                                res += idLen;
                                res += taskID;
                                send(fdSocket.fd_array[i], res.toStdString().c_str(), res.size(), 0);
                                printf("服务器发送停止消息:%s\n", res.toStdString().c_str());
                                delete[] str;
                                str = NULL;
                            
                           
                        }    
                        else if (strncmp(temp, "02", 2) == 0)//停止任务
                        {
                            int length;
                            char contentLen[4];
                            memcpy(contentLen, recvBuf+4, 4);
                            sscanf(contentLen, "%d", &length);
                            char* str = new char[length+1];
                            int size = 0;
                            int ret;
                            while(1)
                            {
                                ret = recv(fdSocket.fd_array[i], str+size, length-size, 0);
                                if (ret > 0)
                                {
                                    size += ret;
                                    if (size == length)
                                    {
                                        break;
                                    }
                                }                              
                            }
                            str[length] = 0;
                            printf("服务器收到停止消息:%s\n", str);
                            Sleep(1000);//模拟停止
                            //响应停止
                            send(fdSocket.fd_array[i], "010000010", 9, 0);
                            printf("服务器响应停止消息:%s\n", "010000010");
                            delete[] str;
                            str = NULL;
                        }
                               
                    }
                }
            }  

        }        
      }
        else if(nRet == SOCKET_ERROR)
        {
            printf("select出错\n");
            break;
        }
        else
        {
            continue;
        }
    }
    printf("程序结束\n");
    closesocket(sockSrv);
    WSACleanup();  
    return 0;  

0 0