写的域套接字文件通信,recv函数出现Invalid argument

//服务器端的
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/un.h>
#include<strings.h>
#include<pthread.h>
#include<arpa/inet.h>
#include<string.h>
#include<signal.h>

typedef struct data
{
	char buff[100];
}Data;

void *pth_fun(void *pth_argv)
{
	int sockfd = -1;
	Data her_data = {0};
	sockfd = socket(PF_UNIX,SOCK_STREAM,0);
	if(sockfd == -1)
	{
		perror("socket");
		exit(-1);
	}
	while(1)
	{
		if(-1 == recv(sockfd,(void *)&her_data,sizeof(her_data),0))
		{
			perror("recv");
			exit(-1);
		}
		printf("%s\n",her_data.buff);
	}

}

void sigrm(int signum)
{
	if(SIGINT == signum)
	{	
		remove("./UNIX_SOCK");
		exit(-1);
	}
}

int main(int argc,char **argv)
{
	int sockfd = -1;
	int fd = -1;
	signal(SIGINT,sigrm);
	sockfd = socket(PF_UNIX,SOCK_STREAM,0);
	if(sockfd == -1)
	{
		perror("socket");
		return 0;
	}
	struct sockaddr_un my_addr = {0};
	my_addr.sun_family = PF_UNIX;
	strcpy(my_addr.sun_path,"./UNIX_SOCK");
	if(-1 == bind(sockfd,(struct sockaddr *)&my_addr,sizeof(my_addr)))
	{
		perror("bind");
		exit(-1);
	}
	if(-1 == listen(sockfd,3))
	{
		perror("listen");
		exit(-1);
	}
	fd = accept(sockfd,NULL,0);
	if(fd == -1)
	{
		perror("accept");
		exit(-1);
	}
	pthread_t pid;
	if(-1 == pthread_create(&pid,NULL,pth_fun,NULL))
	{
		perror("pthread_create");
		exit(-1);
	}
	Data my_data = {0};
	while(1)
	{
		scanf("%s",my_data.buff);
		if(send(fd,(void *)&my_data,sizeof(my_data),0))
		{
			perror("send");
			exit(-1);
		}
	}
	return 0;
}





//客户端的代码
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/un.h>
#include<pthread.h>
#include<arpa/inet.h>
#include<signal.h>
#include<string.h>

typedef struct data
{
	char buff[100];
}Data;

void *pth_fun(void *pth_argv)
{
	int sockfd = -1;
	sockfd = socket(AF_UNIX,SOCK_STREAM,0);
	if(sockfd == -1)
	{
		perror("socket");
		exit(-1);
	}
	Data her_data = {0};
	while(1)
	{
		if(-1 == recv(sockfd,(void *)&her_data,sizeof(her_data),0))
		{
			perror("recv");
			exit(-1);
		}
		printf("%s\n",her_data.buff);
	}
}
void sigram(int signum)
{
	if(signum == SIGINT)
	{
		remove("./UNIX_SOCK");
		exit(-1);
	}
}
int main(int argc,char **argv)
{
	int sockfd = -1;
	struct sockaddr_un seraddr={0};
	signal(SIGINT,sigram);
	sockfd = socket(AF_UNIX,SOCK_STREAM,0);
	if(sockfd == -1)
	{
		perror("socket");
		exit(-1);
	}
	Data my_data = {0};
	seraddr.sun_family = AF_UNIX;
	strcpy(seraddr.sun_path,"./UNIX_SOCK");
	if(-1 == connect(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr)))
	{
		perror("connect");
		exit(-1);
	}
	pthread_t pid;
	pthread_create(&pid,NULL,pth_fun,NULL);
	while(1)
	{
		scanf("%s",my_data.buff);
		if(-1 == send(sockfd,(void *)&my_data,sizeof(my_data),0))
		{
			perror("send");
			exit(-1);
		}
	}

	return 0;
}




 

参考GPT和自己的思路:

根据代码可以看出,服务器端的recv函数出现了Invalid argument的问题,这个错误通常是由于传递给recv函数的某些参数不正确导致的。

具体来说,程序中使用的是UNIX域套接字通信,因此在使用recv函数的时候,需要注意以下几个问题:

  1. 参数sockfd应该是服务器端的套接字描述符,而不是客户端的套接字描述符;

  2. 参数buf应该是一个指向接收数据缓冲区的指针,而不是一个指向Data结构体的指针;

  3. 参数len应该是接收缓冲区的大小,而不是Data结构体的大小。

另外,从代码中可以看出,服务器端的套接字描述符是通过socket函数创建的,而客户端的套接字描述符是通过connect函数创建的,这两个函数中使用的地址族不同,建议在客户端和服务器端中使用相同的地址族。

通过排查以上几个问题,应该可以解决recv函数出现Invalid argument的问题。

参考GPT和自己的思路:

这个问题是因为在服务器端的pthread中,创建socket时使用了PF_UNIX作为协议族,但是在客户端中使用的是 AF_UNIX,导致两端的协议不匹配。正确的做法是在服务器端的pthread中使用 AF_UNIX 替换 PF_UNIX。同时,为了防止recv函数在接收数据时出现Invalid argument的问题,需要在recv函数调用之前先对接收缓冲区进行清空。