c-Winsock2线程参数引发异常访问冲突



我正在用WinSock2.h编程UDP服务器客户端程序,其中各个线程所需的参数(SOCKETsockaddr_in(通过结构传递给线程。

每当我的receive函数到达recvfrom()部分时,它都会不断抛出异常,但只有在调试程序时才会抛出。如果我在没有调试器的情况下启动它,它不会显示任何错误,也不会停止程序的运行。此异常仅发生在服务器一侧。此外,recvfrom()错误检查不断在客户端抛出错误10022,但据我所知,这是由于客户端没有bind()造成的。

服务器端是否存在bind()在另一个函数中的问题,或者我的指针是否有问题?我没有任何其他想法,为什么它只在服务器端抛出异常。

typedef struct thread_args {
struct sockaddr_in sockaddr;
SOCKET socket;
int keep_alive_count; 
}THREAD_ARG;
void* receive_packets(void* arguments) {
THREAD_ARG* args = (THREAD_ARG*)arguments;
struct sockaddr_in* from;
char buffer[MAX_FRAGMENTATION + sizeof(HEADER)];
HEADER* message;
while (1) {
memset(buffer, "", MAX_FRAGMENTATION + sizeof(HEADER));
//this is where I get the exception thrown
if (recvfrom(args->socket, buffer, sizeof(buffer), 0, (struct sockaddr*) & from, sizeof(from)) == SOCKET_ERROR) { 
printf("recvfrom() failed, error code: %dn", WSAGetLastError());
exit(RECVFAIL);
}
message = (HEADER*)buffer;
char flag = message->flags;
}
}
return 0;
}
int client(THREAD_ARG* args) {
u_short port;
char ip[50];
struct sockaddr_in client_sock;
void* return_value1, *return_value2;
getchar();
printf("Please enter the IP address you would like to communicate with:n");
gets(IP);
printf("Please enter the port number you would like to communicate with:n");
scanf("%hu", &port);
client_sock.sin_family = AF_INET;
client_sock.sin_addr.s_addr = inet_addr(IP);
client_sock.sin_port = htons(port);
args->sockaddr = client_sock;
pthread_t send_thread, receive_thread, keep_alive_thread;
pthread_create(&send_thread, NULL, send_packets, args);
pthread_create(&receive_thread, NULL, receive_packets, args);
pthread_create(&keep_alive_thread, NULL, keep_alive, args);
pthread_join(send_thread, &return_value1);
pthread_join(receive_thread, &return_value2);
pthread_join(keep_alive_thread, NULL);
return 0;
}
int server(THREAD_ARG* args) {
u_short port;
int valid;
struct sockaddr_in server_sock;
void* return_value1, * return_value2;
printf("Please enter the port number you would like to listen on:n");
scanf("%hu", &port);
server_sock.sin_family = AF_INET;
server_sock.sin_addr.s_addr = INADDR_ANY;
server_sock.sin_port = htons(port);
if(bind(args->socket, (struct sockaddr_in*) & server_sock, sizeof(server_sock)) == SOCKET_ERROR) {
printf("Bind failed, error code: %dn", WSAGetLastError());
return 1;
}
printf("Bind donen");
args->sockaddr = server_sock;
pthread_t receive_thread;
pthread_create(&receive_thread, NULL, receive_packets, args);
pthread_join(receive_thread, &return_value2);
}
int main() {
WSADATA was;
SOCKET sock;
char choice;
THREAD_ARG* args;
printf("WinSock initialisation.n");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("WinSock initialisation failed. Error code: %dn", WSAGetLastError());
return 1;
}
printf("WinSock initialised.");
if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
printf("Couldn't create socket: %dn", WSAGetLastError());
}
printf("Socket created.n");
printf("Would you like to be a server or a client?n");
printf("1 - Servern");
printf("2 - Clientn");
printf("0 - Exitn");
args = (THREAD_ARG*)malloc(sizeof(THREAD_ARG));
args->socket = sock;
switch (choice = getchar())
{
case '0':
return 0;
case '1':
server(args);
break;
case '2':
client(args);
break;
default:
printf("Please choose from aboven");
}
return 0;
}
struct sockaddr_in* from;
char buffer[MAX_FRAGMENTATION + sizeof(HEADER)];
HEADER* message;

你有问题。您只分配了一个sockaddr_in*。但您需要一个实际的sockaddr_in来保存地址。

while (1) {
memset(buffer, "", MAX_FRAGMENTATION + sizeof(HEADER));

这里,memset的第二个参数是错误的。它应该是要设置的值,而不是指向某个值的指针。

if (recvfrom(args->socket, buffer, sizeof(buffer), 0, (struct sockaddr*) & from, sizeof(from)) == SOCKET_ERROR) { 

在这里,您将struct sockaddr_in **强制转换为struct sockaddr *,去掉了一个间接级别。这没有任何意义。最后一个参数sizeof(from)指针的大小。这是不对的。

THREAD_ARG* args;
...
args = (THREAD_ARG*)malloc(sizeof(THREAD_ARG));
args->socket = sock;

为什么这种奇怪的间接方式?为什么不只是THREAD_ARD args;,去掉malloc->的东西?

相关内容

  • 没有找到相关文章