首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

關於 ws2_32.dll 中的 recv() 函式使用問題

2012-02-09 
求助 關於 ws2_32.dll 中的 recv() 函式使用問題因為最近打算學習 winsock hook, 所以想說先練習基本的 Lo

求助 關於 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楼的代码中,函数指针的声明有问题,将

C/C++ code
  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); 

热点排行