0

私はC++で非同期サーバーリスナーを作成しようとしていますが、C ++は初めてですが、このプロジェクトを実行する必要があります。私はWeb開発者(PHP)ですが、PHPは非同期接続を確立できません+彼は大量の接続に対して非常に貧弱な言語です...非同期なしで単純なリスナーを作成できますが、「CreateThread」に問題があります...たとえば、クライアントが接続されている場合、コンソールはこれに関する結果を返します+スニファーはそれを修正できます...10秒後にクライアントは私を送信する必要があります再び異なるデータを持つ同じパケット。私のコンソールはそのパケットについての結果を私に与えませんが、スニファはそのパケットを見ることができます...誰かが私の問題を見ることができれば私を説明してください...(私の悪い英語:D)

#include <winsock2.h>
#include <windows.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>

DWORD WINAPI SocketHandler(void*);

int main(int argv, char** argc){

    //The port you want the server to listen on
    int host_port = 7878;

    //Initialize socket support WINDOWS ONLY!
    unsigned short wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MAKEWORD( 2, 2 );
     err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 || ( LOBYTE( wsaData.wVersion ) != 2 ||
            HIBYTE( wsaData.wVersion ) != 2 )) {
        fprintf(stderr, "Could not find useable sock dll %d\n",WSAGetLastError());

    }

    //Initialize sockets and set any options
    int hsock;
    int * p_int ;
    hsock = socket(AF_INET, SOCK_STREAM, 0);
    if(hsock == -1){
        printf("Error initializing socket %d\n",WSAGetLastError());

    }

    p_int = (int*)malloc(sizeof(int));
    *p_int = 1;
    if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
        (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
        printf("Error setting options %d\n", WSAGetLastError());
        free(p_int);

    }

    free(p_int);

    //Bind and listen
    struct sockaddr_in my_addr;

    my_addr.sin_family = AF_INET ;
    my_addr.sin_port = htons(host_port);

    memset(&(my_addr.sin_zero), 0, 8);
    my_addr.sin_addr.s_addr = INADDR_ANY ;

    if( bind( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){
        fprintf(stderr,"Error binding to socket, make sure nothing else is listening on this port %d\n",WSAGetLastError());

    }
    if(listen( hsock, 10) == -1 ){
        fprintf(stderr, "Error listening %d\n",WSAGetLastError());

    }

    //Now lets to the server stuff

    int* csock;
    sockaddr_in sadr;
    int    addr_size = sizeof(SOCKADDR);

    while(true){
        printf("waiting for a connection\n");
        csock = (int*)malloc(sizeof(int));

        if((*csock = accept( hsock, (SOCKADDR*)&sadr, &addr_size))!= INVALID_SOCKET ){
            printf("Received connection from %s",inet_ntoa(sadr.sin_addr));
            CreateThread(0,0,&SocketHandler, (void*)csock , 0,0);
        }
        else{
            fprintf(stderr, "Error accepting %d\n",WSAGetLastError());
        }
    }


}

DWORD WINAPI SocketHandler(void* lp){

    int *csock = (int*)lp;
    char buffer[1024];  
    int buffer_len = 1024;
    int bytecount;
    memset(buffer, 0, buffer_len);
    if((bytecount = recv(*csock, buffer, buffer_len, 0))==SOCKET_ERROR){
        fprintf(stderr, "Error receiving data %d\n", WSAGetLastError());   
    }
    printf("Received bytes %d\n Received string \"%s\"\n", bytecount, buffer);



    char buff[1] = {0x11};        
    if((bytecount = send(*csock, buff, 1, 0))==SOCKET_ERROR){
        fprintf(stderr, "Error sending data %d\n", WSAGetLastError());    
    }

    printf("Sent bytes: %d. Send Message: %s\n ", bytecount,buff);


    free(csock);

}
4

1 に答える 1

1

問題はスレッドの作成ではなく、データの受け渡しにあると思われます。ソケットをスレッドに渡すだけの方がおそらく簡単です。さらに、関数の最後にメモリを正しく解放しましたが、ソケットを閉じませんでした。変更を加え、正しく機能することを確認しました。私が行った変更は // *のコメントです

#include <winsock2.h>
#include <windows.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>

DWORD WINAPI SocketHandler(void*);

//*** Changed to work with my version of 
//*** Visual Studio
int _tmain(int argc, _TCHAR* argv[]){

//The port you want the server to listen on
int host_port = 7878;

//Initialize socket support WINDOWS ONLY!
unsigned short wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
 err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 || ( LOBYTE( wsaData.wVersion ) != 2 ||
    HIBYTE( wsaData.wVersion ) != 2 )) {
    fprintf(stderr, "Could not find useable sock dll %d\n",WSAGetLastError());
}

//Initialize sockets and set any options
    //*** Changed to be SOCKET instead of int
SOCKET hsock;
int * p_int ;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if(hsock == -1){
    printf("Error initializing socket %d\n",WSAGetLastError());
}

p_int = (int*)malloc(sizeof(int));
*p_int = 1;
if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
    (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
    printf("Error setting options %d\n", WSAGetLastError());
    free(p_int);
}

free(p_int);

//Bind and listen
struct sockaddr_in my_addr;

my_addr.sin_family = AF_INET ;
my_addr.sin_port = htons(host_port);

memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = INADDR_ANY ;

if( bind( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){
    fprintf(stderr,"Error binding to socket, make sure nothing else is listening on this port %d\n",WSAGetLastError());
}
if(listen( hsock, 10) == -1 ){
    fprintf(stderr, "Error listening %d\n",WSAGetLastError());
}

//Now lets to the server stuff
    //*** Changed to be SOCKET instead of int* 
SOCKET csock;
sockaddr_in sadr;
int    addr_size = sizeof(SOCKADDR);

while(true){
    printf("waiting for a connection\n");
        //*** Changed to comment out line as it is not needed
   // csock = (SOCKET)malloc(sizeof(SOCKET));
        //*** Changed check to be INVALID_SOCKET
    if((csock = accept( hsock, (SOCKADDR*)&sadr, &addr_size))!= INVALID_SOCKET ){
    printf("Received connection from %s",inet_ntoa(sadr.sin_addr));
            //*** Changed to pass the client socket
    CreateThread(0,0,&SocketHandler, (void*)csock , 0,0);
    }
    else{
    fprintf(stderr, "Error accepting %d\n",WSAGetLastError());
    }
}
}

DWORD WINAPI SocketHandler(void* lp){

    //** Changed to cast as the SOCKET which was passed
SOCKET csock = (SOCKET)lp;
char buffer[1024];  
int buffer_len = 1024;
int bytecount;
memset(buffer, 0, buffer_len);
if((bytecount = recv(csock, buffer, buffer_len, 0))==SOCKET_ERROR){
    fprintf(stderr, "Error receiving data %d\n", WSAGetLastError());   
}
printf("Received bytes: %d\nReceived string: \"%s\"\n", bytecount, buffer);

char buff[1] = {0x11};        
if((bytecount = send(csock, buff, 1, 0))==SOCKET_ERROR){
    fprintf(stderr, "Error sending data %d\n", WSAGetLastError());    
}

printf("Sent bytes: %d. Send Message: %s\n ", bytecount,buff);

    //*** Changed to close the socket after the message is sent. Otherwise
    //*** the socket would remain open
    closesocket(csock);

    //*** Changed to comment the line out as there is 
    //*** no allocated memory.
//free(csock);

    return 0;
}
于 2013-02-23T17:30:43.097 に答える