0

首先,我对 C++ 还是很陌生。我正在尝试编写一个 GNSS 互联网广播播客程序。基本上,当客户端登录并被接受时,我的程序将客户端请求的数据流源存储在客户端类中。我打算使用两个数组的索引号来匹配一个 Client 对象数组和一个 clientSockets 数组,但是尝试使用 Select() 检查非阻塞套接字会使事情变得复杂。我找到了一些实现 Select() 的示例,但我不确定如何从我用来接受来自 listenSocket 的连接的数组中跟踪原始 clientSocket。

    class Client{
            public:
            std::string  source;
            std::string  user;   //stored in txt file as name:password
            boolean      connected;
            int          IndexNumber;

    };
typedef struct _MYSOCKET_INFORMATION{
  char Buffer[BUFFERSIZE];
  WSABUF DataBuf;
  SOCKET Socket;
  DWORD SendBytes;
  DWORD RecvBytes;
}SOCKET_INFORMATION, *LPSOCKET_INFORMATION;
// creates number of objects of this structure
LPSOCKET_INFORMATION SocketList[NUMBER_CLIENTS];

FD_SET Writer;
FD_SET Reader;
DWORD TotalSockets = 0;
DWORD Flags;
u_long NonBlock = 1;
timeval tv;
long tv_sec = 1;
long tv_usec = 0;
//intiate objects
Caster caster;
DataStream datastream[NUMBER_BASES]; //100 base stations max
Client client[NUMBER_CLIENTS];
SOCKET listenSocket;
SOCKET clientSocket[NUMBER_CLIENTS];
SOCKET serverSocket;
char recvArray[BUFFERSIZE];
using namespace std;
int main()
{
//initialize the Read and Write socket sets
    FD_ZERO(&Reader);
    FD_ZERO(&Writer);
    //check for connection attempt
    FD_SET(listenSocket, &Reader);
    FD_SET(serverSocket, &Reader);
    //set read and write state based on state of buffer

    for( unsigned int i=0; i<TotalSockets; i++){
        if( SocketList[i]->RecvBytes < SocketList[i]->SendBytes){
            FD_SET(SocketList[i]->Socket,&Writer);
        }
        else{
            FD_SET(SocketList[i]->Socket,&Reader);
        }
    }

    //Select returns number of sockets ready to be read/writen
    Total = select(0, &Reader, &Writer, NULL, &tv);
    if(Total == SOCKET_ERROR){
        printf("Error select function %d\n", WSAGetLastError());
        return 1;
    }
if( FD_ISSET(listenSocket, &Reader)){
        Total--;
        //set current client no
        while(client[current].connected == true){
            current++;
            if(current >= NUMBER_CLIENTS){
                current = 0;
                count++;
                if(count >= 2){//has cylcled twice all must be set to true, can add no more.
                    count =0;
                    printf("client limit reached.\n");
                    break;
                }
            }
        }
        clientSocket[current] = accept(listenSocket, NULL, NULL); //setup client connection for further use
        if( clientSocket[current] != INVALID_SOCKET){
        //set new client to non blocking
            check = ioctlsocket(clientSocket[current], FIONBIO, &NonBlock);
            if( check == SOCKET_ERROR){
                printf("Error setting client to nonblocking mode. %d.\n", WSAGetLastError());
                closesocket(clientSocket[current]);
                continue;
            }
            else{
                printf("Accepted client connection request \n");
            //recieve data
                check = recv(clientSocket[current], recvArray, BUFFERSIZE, 0);
                if( check == SOCKET_ERROR){  //close connection if error
                    printf("error recieving login data. %d \n", WSAGetLastError());
                    closesocket(clientSocket[current]);
                    continue;
                }
                if( check == 0){//no data is recieved then client disconnected
                    printf("ERROR no data, client dsiconnected.\n");
                    closesocket(clientSocket[current]);
                    continue;
                }
                else{

                    for(int n=0; n<check +1 ; n++){    //must be request message for data per NTRIP 1.0
                        clientRequest << recvArray[n]; //place read char bytes into stringstream object for parsing.
                    }
                    //if request is good returns a client requested source, username, and true false for data send.
                    checkClientRequest(clientSocket[current], client[current].source, client[current].connected, client[current].user);

                }
            }
        }
    }//end of check client listen socket
for(unsigned int i=0; Total>0 && i<TotalSockets; i++){
        LPSOCKET_INFORMATION SocketInfo = SocketList[i];
        //check if client sends GGA string
        if(FD_ISSET(SocketInfo->Socket, &Reader)){
            Total--;
            SocketInfo->DataBuf.buf = SocketInfo->Buffer;
            SocketInfo->DataBuf.len = BUFFERSIZE;
            Flags = 0;
            SocketInfo->RecvBytes = sizeof(SocketInfo->DataBuf);
            check = WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &(SocketInfo->RecvBytes), &Flags, NULL, NULL);
            if( check == SOCKET_ERROR){
                FreeSocketInformation(i); //shuts down client socket if socket error
                continue;
            }
            else{
            memcpy(recvArray, SocketInfo->DataBuf.buf, SocketInfo->RecvBytes +1);
            //print data on screen change to sort lines
            printf("%s \n", SocketInfo->DataBuf.buf);
            }
        }

它不仅限于此,但如何使用我的 clientSocket[] 跟踪结构 SocketInfo?

4

0 回答 0