c - Socket loses connection on send() -


edit : scroll down see updated code.

i build fake player minecraft, in c language.

my minecraft server (bukkit) listening on port 25565, on local ip 192.168.1.141

when launch application, (when send data trough socket) bukkit server says : "192.168.1.141:xxxxx lost connection", and

my application tell me :

socked created socked connected send data = (smilie)kekos91;192.168.1.141:25565 send length = 27 send ! response data = (a strange symbol) response length = 1 socket disconnected 

maybe because of char-set ? know why ? here code :

#include <stdio.h> #include <stdlib.h> #include <windows.h> #include <winsock2.h>  int main() {     char pseudo[] = "kekos91;192.168.1.141:25565";     int pseudolen = strlen(pseudo);      char *packet = null;     packet = (char*)malloc(3 + ((pseudolen)*sizeof(char)*2));     if(packet == null)     {         return -1;     }     memset(packet, '\0', sizeof(packet));     packet[0] = (char)0x02;     strcat(packet, pseudo);     int plenght = strlen(packet);      char handshake[200];      handle hconsole;     wsadata wsadata;     int iresult = 0;      socket serversocket;     sockaddr_in serverinfos;      iresult = wsastartup(makeword(2, 2), &wsadata);     if (iresult != no_error) {         printf("wsastartup() failed error: %d\n", iresult);         return -1;     }      serversocket = socket(af_inet, sock_stream, ipproto_tcp);     if (serversocket == invalid_socket) {         printf("socket function failed error: %i\n", wsagetlasterror());         wsacleanup();         return -1;     }     printf("socket created\n");      serverinfos.sin_family = af_inet;     serverinfos.sin_addr.s_addr = inet_addr("192.168.1.141");     serverinfos.sin_port = htons(25565);      iresult = connect(serversocket, (sockaddr *)&serverinfos, sizeof(serverinfos));     if (iresult == socket_error)     {         printf("connect function failed error: %i\n", wsagetlasterror());         iresult = closesocket(serversocket);         if (iresult == socket_error)         {            printf("closesocket function failed error: %i\n", wsagetlasterror());         }         wsacleanup();         return -1;     }     printf("socket connected\n");        printf("to send data = %s\n", packet);     printf("to send length = %i\n", pseudolen);     sleep(500); // after point, connection loose :(     if(send(serversocket, (char*)packet , plenght, 0) == socket_error)     {         printf("send function failed error: %i\n", wsagetlasterror());         iresult = closesocket(serversocket);         if (iresult == socket_error)         {            printf("closesocket function failed error: %i\n", wsagetlasterror());         }         wsacleanup();         return -1;     }     free(packet);      printf("send !\n");         if(recv(serversocket, (char*)&handshake, 200, 0) == socket_error)     {         printf("recv function failed error: %i\n", wsagetlasterror());         iresult = closesocket(serversocket);         if (iresult == socket_error)         {            printf("closesocket function failed error: %i\n", wsagetlasterror());         }         wsacleanup();         return -1;     }      printf("response data = %s\n", handshake);           printf("response length = %i\n", strlen(handshake));       iresult = closesocket(serversocket);     if (iresult == socket_error) {         printf("closesocket function failed error %i\n", wsagetlasterror());         wsacleanup();         return -1;     }     printf("socket disconnected.\n");      wsacleanup();     sleep(5000);     return 0; } 

thanks in advance, , please excuse bad english :)

update :

thanks constructive comments, works now. here working code see going on old code.

#include <stdio.h> #include <stdlib.h> #include <windows.h> #include <winsock2.h>  int main() {     int isocketresult = 0; // retrieve sockets return functions, send / recv / errors      wchar_t wcpseudo[] = l"kekos91;192.168.1.141:25565";     int ipseudolen = wcslen(wcpseudo);      char *ppacket = null;     ppacket = (char*)malloc(3 + ((ipseudolen)*sizeof(char)*2));     if(ppacket == null)     {         return -1;     }     ppacket[0] = 0x02;       *(short*)( ppacket + 1 ) = htons( ipseudolen );     memcpy( ppacket + 3, wcpseudo, ipseudolen * sizeof( wchar_t ));      int ipacketlen = 3 + ipseudolen*sizeof(wchar_t) ;          char *handshake  = null;     handshake = (char*)malloc(sizeof(char)*200);     if(handshake == null)     {         return -1;     }       handle hconsole;     wsadata wsadata;              socket serversocket;     sockaddr_in serverinfos;      isocketresult = wsastartup(makeword(2, 2), &wsadata);     if (isocketresult != no_error) {         printf("wsastartup() failed error: %d\n", isocketresult);         return -1;     }      serversocket = socket(af_inet, sock_stream, ipproto_tcp);     if (serversocket == invalid_socket) {         printf("socket function failed error: %i\n", wsagetlasterror());         wsacleanup();         return -1;     }      printf("socket created\n");      serverinfos.sin_family = af_inet;     serverinfos.sin_addr.s_addr = inet_addr("192.168.1.141");     serverinfos.sin_port = htons(25565);      isocketresult = connect(serversocket, (sockaddr *)&serverinfos, sizeof(serverinfos));     if (isocketresult == socket_error)     {         printf("connect function failed error: %i\n", wsagetlasterror());         isocketresult = closesocket(serversocket);         if (isocketresult == socket_error)         {            printf("closesocket function failed error: %i\n", wsagetlasterror());         }         wsacleanup();         return -1;     }     printf("socket connected\n\n");      printf("to send protocol = %#1.2x \nlenght = %i\n", ppacket[0], ipseudolen);      isocketresult = send(serversocket, ppacket , ipacketlen, 0);     if(isocketresult == socket_error)     {         printf("send function failed error: %i\n", wsagetlasterror());         isocketresult = closesocket(serversocket);         if (isocketresult == socket_error)         {            printf("closesocket function failed error: %i\n", wsagetlasterror());         }         wsacleanup();         return -1;     }     free(ppacket);      printf("send %i (bytes) !\n\n",isocketresult);       isocketresult = recv(serversocket, handshake, 50, 0);     if( isocketresult == socket_error)     {         printf("recv function failed error: %i\n", wsagetlasterror());         isocketresult = closesocket(serversocket);         if (isocketresult == socket_error)         {            printf("closesocket function failed error: %i\n", wsagetlasterror());         }         wsacleanup();         return -1;     }      printf("response protocol = %#1.2x\nresponse lenght = %i (bytes)\n\n", handshake[0], isocketresult);     free(handshake);           isocketresult = closesocket(serversocket);     if (isocketresult == socket_error)     {         printf("closesocket function failed error %i\n", wsagetlasterror());         wsacleanup();         return -1;     }     printf("socket disconnected.\n");      wsacleanup();     sleep(7000);     return 0; } 

the output console prints :

socket created socket connected  send protocol = 0x02  lenght = 27 send 57 (bytes) !  response protocol = 0x02 response lenght = 37 (bytes)  socket disconnected. 

thanks !

in general, doing appears correct. imagine "connection lost" message server happens when test code closes own socket. however, looks not handling string data type correctly. string needs sent unicode, , appears sending single-byte characters. also, string needs preceded length represented 2 byte integer.

the handshake string should maybe instead specified follows wchar_t (or favorite wide character data type). , use l on literal specify wide string. actual send length in bytes needs sure multiply string length 2.

wchar_t pseudo[] = l"kekos91;192.168.1.141:25565"; int pseudolen = wcslen(pseudo);

then, likewise, use wide string function copy string (strcat won't work).

to put string length in 2 bytes after 0x02 protocol code, might this:

*((short*)( packet + 1 ) = htons( pseudollen ); 

to copy string packet, maybe (i'm writing on fly without compiling:

memcpy( packet + 3, pseudo, pseudolen * sizeof( wchar_t )); 

the actual send length in bytes be: 3 + pseudolen * sizeof( wchar_t )

when printing resulting response, might want:

printf( "protocol response: %02x\n", handshake[0] ); 

and extract string (the 2 bytes following protocol byte should length of connection hash string (in network byte order). need use ntohs extract it. , following n wide characters represent hash.

having written that, seems me might want library deal protocols. have not looked, seems there minecraft-related sockets library c available. wild guess. edit on second thought, depends on goals. if wanting build client fast possible, makes sense library. if, however, wanting learn details of protocol, network programming, etc. writing @ level started idea , lot of fun since can make incremental steps show real results quite often.

one other thing. memset after allocating memory might not doing expect. assuming 32-bit architecture, sizeof( packet ) 4 (it's 4 byte pointer). however, since filling packet in data, memset isn't necessary.


Comments

Popular posts from this blog

c# - SVN Error : "svnadmin: E205000: Too many arguments" -

c++ - Using OpenSSL in a multi-threaded application -

All overlapping substrings matching a java regex -