user1360571
user1360571

Reputation: 1

C++ CreateThread does not show result

i'm trying make asynchronous server listener with C++ i'm new in c++ but i must do this project , i'm web developer (PHP) but PHP can't make async connections + he is very poor language for big amount of connections... i can write simple listener without asynchronous but now i have problem with "CreateThread"... for example if client has been connected console gives me result about this + sniffer can fix it... after 10 sec client must send me again same packet with different data. my console does not gives me result about that packet but sniffer can see that packet... please if anyone can see my problem explain me ... (sorry for my bad english :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);

}

Upvotes: 0

Views: 790

Answers (1)

Glenn
Glenn

Reputation: 1177

I suspect the issue not be the creating a thread, but in the passing of the data. It is probably simpler to just pass the socket to the thread. Additionally, at the end of the function you correctly free the memory, but you did not close the socket. I have made changes and verified that it functions correctly. The changes I made are comments with //*

#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;
}

Upvotes: 1

Related Questions