求助 關於 ws2_32.dll 中的 recv() 函式使用問題
因為最近打算學習 winsock hook, 所以想說先練習基本的 LoadLibrary(),
GetProcAddress() ..., 下面程式碼是一個簡單的 client 端, 在 LoadLibrary
和 GetProcAddress 部分都能正常抓到值, 但是呢.. 只要程式一執行到 recv()
函式 (len = (*precv)(conn_sock, buf, sizeof(buf) - 1, 0) 這段), 程式就
會死亡 (windows xp 會跳出程式必須關閉的訊息視窗), 如果把 recv() 註解掉
直接跑 send(), 程式就能正常結束, 想請教為何會這樣呢, 謝謝.
原本是用 BCC5.5 編譯, 後來有拿到 BCB6 編譯, 但是結果還是一樣.
程式參數:
client.exe <server ip> <server port>
=====================================================================
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock2.h>
#define GET_FUNC_ADDR(dll_handle, func_ptr, func_name, error_proc) \
do \
{ \
if(((FARPROC) func_ptr = GetProcAddress(dll_handle, func_name)) == NULL) \
{ \
printf("call GetProcAddress(%s) fail\n", func_name); \
goto error_proc; \
} \
printf("call GetProcAddress(%s) pass, address = 0x%p\n", func_name, func_ptr); \
} \
while(0)
int main(int argc, char **argv)
{
HINSTANCE socket_dll;
WSADATA wsa_data;
SOCKET conn_sock;
SOCKADDR_IN conn_addr;
int len;
char buf[2048] = {0};
int (*pWSAStartup)(WORD, LPWSADATA);
int (*pWSACleanup)(void);
int (*psocket)(int, int, int);
int (*pclosesocket)(SOCKET);
int (*pconnect)(SOCKET, const struct sockaddr *, int);
int (*precv)(SOCKET, char *, int, int);
int (*psend)(SOCKET, const char *, int, int);
if(argc < 3)
goto FREE_01;
if((socket_dll = LoadLibrary("ws2_32.dll")) == NULL)
{
printf("call LoadLibrary() fail\n");
goto FREE_01;
}
printf("call LoadLibrary() pass, handle = %d\n", socket_dll);
GET_FUNC_ADDR(socket_dll, pWSAStartup, "WSAStartup", FREE_02);
GET_FUNC_ADDR(socket_dll, pWSACleanup, "WSACleanup", FREE_02);
GET_FUNC_ADDR(socket_dll, psocket, "socket", FREE_02);
GET_FUNC_ADDR(socket_dll, pclosesocket, "closesocket", FREE_02);
GET_FUNC_ADDR(socket_dll, pconnect, "connect", FREE_02);
GET_FUNC_ADDR(socket_dll, precv, "recv", FREE_02);
GET_FUNC_ADDR(socket_dll, psend, "send", FREE_02);
if((*pWSAStartup)(MAKEWORD(2, 2), &wsa_data) < 0)
{
printf("call WSAStartup() fail\n");
goto FREE_02;
}
printf("call WSAStartup() pass\n");
if((conn_sock = (*psocket)(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("call socket() fail\n");
goto FREE_03;
}
printf("call socket() pass\n");
memset(&conn_addr, 0, sizeof(SOCKADDR_IN));
conn_addr.sin_family = AF_INET;
conn_addr.sin_addr.s_addr = inet_addr(argv[1]);
conn_addr.sin_port = htons(atoi(argv[2]));
if((*pconnect)(conn_sock, (SOCKADDR *) &conn_addr, sizeof(SOCKADDR)) == SOCKET_ERROR)
{
printf("call connect() fail\n");
goto FREE_04;
}
printf("call connect() pass\n");
if((len = (*precv)(conn_sock, buf, sizeof(buf) - 1, 0)) < 0)
{
printf("call recv() fail\n");
goto FREE_04;
}
printf("call recv() pass\n");
buf[len] = '\0';
if((len = (*psend)(conn_sock, buf, strlen(buf) + 1, 0)) < 0)
{
printf("call send() fail\n");
goto FREE_04;
}
printf("call send() pass\n");
FREE_04:
(*pclosesocket)(conn_sock);
printf("call closesocket() pass\n");
FREE_03:
(*pWSACleanup)();
printf("call WSACleanup() pass\n");
FREE_02:
FreeLibrary(socket_dll);
CloseHandle(socket_dll);
FREE_01:
return 0;
}
[解决办法]
应该是楼主在0楼的代码中,函数指针的声明有问题,将
int (*pWSAStartup)(WORD, LPWSADATA); int (*pWSACleanup)(void); int (*psocket)(int, int, int); int (*pclosesocket)(SOCKET); int (*pconnect)(SOCKET, const struct sockaddr *, int); int (*precv)(SOCKET, char *, int, int); int (*psend)(SOCKET, const char *, int, int);