такая проблема: пишу радмин. испольузю бинарный протокол как у мэйлагента(очень удобно - сначала заголовок, потом данные четырехбайтные целые и строки с префиксной длиной). вот при авторизации возникла проблема: строки некорректно читаются(идет префиксная длина-логин-префиксная длина - пароль). с скоета считывается область памяти(void * или на winapi LPVOID) из нее через memcpy выделяются данные. так вот логин вообще пустой, а вместо пароля какаято кракозябра. вот код: Code: if((pack.command==CS_LOGIN)&&(pack.sing==SIGN)) { wprintf(L"Login reques recived.checking autorization data...\n"); void *lpData=malloc(1024); ZeroMemory(lpData,1024); if(recv(AcceptSocket,(char *)lpData,pack.datalen,0)>0) { FILE *fFile=fopen("test.bin","w"); fwrite(lpData,pack.datalen,1,fFile); fclose(fFile); DWORD dwOffset=0; DWORD dwLoginLen=0; dwOffset+=sizeof(DWORD); memcpy(&dwLoginLen,lpData,dwOffset); char *szLogin=(char *)malloc(256); ZeroMemory(szLogin,256); dwOffset+=dwLoginLen; memcpy(szLogin,lpData,dwOffset); DWORD dwPassLen=0; dwOffset+=sizeof(DWORD); memcpy(&dwPassLen,lpData,dwOffset); char *szPass=(char *)malloc(256); ZeroMemory(szPass,256); dwOffset+=dwPassLen; memcpy(szPass,lpData,dwOffset); strcat(szLogin,"\0"); strcat(szPass,"\0"); printf("loginLen: %d; Login %s; PassLen: %d; Pass: %s; recived: %d; readed: %d",dwLoginLen,szLogin,dwPassLen,szPass,pack.datalen,dwOffset); if(validAuth(szLogin,szPass)) { pack.command=SC_LOGIN_OK; pack.datalen=0; send(AcceptSocket,(char *)&pack,sizeof(pack),0); wprintf(L"login ok. login_ok pack sended..."); } else { pack.command=SC_LOGIN_FAIL; pack.datalen=0; send(AcceptSocket,(char *)&pack,sizeof(pack),0); wprintf(L"login fail!. login_fail pack sended..."); } } } вот содержимое файла test.bin(в него записывается то сто приходит на сокет после заголовка). все корректно и правильно прислано: вот как видно переменные под отладчиком встроенным в visual studio: szLogin И szPass имеют некорректные значения. как решить подобную проблему?
ну а указатель в lpData кто будет перемещать, и уж если у тебя есть длина строки, то и выделяй под нее сколь нужно памяти, а не "гадай" фиксированными значениями а у тебя сейчас так выходит: Code: dwOffset+=sizeof(DWORD); // скопировал в dwLoginLen 4 первых байта из lpData memcpy(&dwLoginLen,lpData,dwOffset); char *szLogin=(char *)malloc(256); ZeroMemory(szLogin,256); // dwOffset присваиваешь сколь надо скопировать байт dwOffset+=dwLoginLen; // скопировал в szLogin первых dwOffset байт из lpData memcpy(szLogin,lpData,dwOffset);
спасибо.понял свою ошибку.переделал вот так: Code: if((pack.command==CS_LOGIN)&&(pack.sing==SIGN)) { wprintf(L"Login reques recived.checking autorization data...\n"); void *lpData=malloc(1024); ZeroMemory(lpData,1024); if(recv(AcceptSocket,(char *)lpData,pack.datalen,0)>0) { FILE *fFile=fopen("test.bin","w"); fwrite(lpData,pack.datalen,1,fFile); fclose(fFile); DWORD dwOffset=0; DWORD dwLoginLen=0; memcpy(&dwLoginLen,(void *)((DWORD)lpData+dwOffset),sizeof(DWORD)); dwOffset+=sizeof(DWORD); char *szLogin=(char *)malloc(dwLoginLen); ZeroMemory(szLogin,dwLoginLen); memcpy(szLogin,(void *)((DWORD)lpData+dwOffset),dwLoginLen); dwOffset+=dwLoginLen; DWORD dwPassLen=0; memcpy(&dwPassLen,(void *)((DWORD)lpData+dwOffset),sizeof(DWORD)); dwOffset+=sizeof(DWORD); char *szPass=(char *)malloc(dwPassLen); ZeroMemory(szPass,dwPassLen); memcpy(szPass,(void *)((DWORD)lpData+dwOffset),dwPassLen); dwOffset+=dwPassLen; printf("loginLen: %d; Login %s; PassLen: %d; Pass: %s; recived: %d; readed: %d",dwLoginLen,szLogin,dwPassLen,szPass,pack.datalen,dwOffset); if(validAuth(szLogin,szPass)) { pack.command=SC_LOGIN_OK; pack.datalen=0; send(AcceptSocket,(char *)&pack,sizeof(pack),0); wprintf(L"login ok. login_ok pack sended..."); } else { pack.command=SC_LOGIN_FAIL; pack.datalen=0; send(AcceptSocket,(char *)&pack,sizeof(pack),0); wprintf(L"login fail!. login_fail pack sended..."); } } } только теперь в конце строк кроме того что нужно появляется еще какаято херня: как сделать чтобы в строке было только то сто нужно без этих кракозябр на конце?
выделяй память на 1 символ больше и ставь ноль в конце, и вообще сделай что-то типа класса или макросов, которые тебе будут возвращать элементарный данные в виде int DWORD, BYTE, char *, в дальнейшем это тебе очень упростит разбор ответов