Linux下C插座:"坏的文件描述符"发生在接受()调用 [英] Linux C Socket:"bad file descriptor" occurs when accept() invokes
问题描述
我写一个发送/使用Linux /插座/ TCP接收项目,我创建了一些线程发送或收到的消息,并使用一个全球性的队列来存储信息
code:
I am writing a send/receive project using linux/socket/tcp, I create some threads to send or recieve message,and use a global queue to store message Code:
void EnQueue (M_queue queue,char * message,char * target_IP,char * target_IP_BAK)
{
char a;
char * m=&a;
strcpy(m,target_IP);
M_element node=(M_element)malloc(sizeof(struct MessageNode ));
node->message=message;
node->target_IP=target_IP;
node->next=NULL;
if(IsQueueEmpty(queue))
{
queue->rear=queue->front=node;
}
else
{
queue->rear->next=node;
queue->rear=node;
}
}
M_queue messages;
void* receive_message();
void* send_message(void* args);
int main()
{
pthread_t in_thread,out_thread;
messages=(M_queue)malloc(sizeof(struct MessageQueue));
init(messages);
int ret=pthread_create(&in_thread,NULL,receive_message,NULL);
if(ret==-1)
{
perror("thread receive:");
}
while(1)
{
if(!IsQueueEmpty(messages))
{
M_element message=DeQueue(messages);
pthread_create(&out_thread,NULL,send_message,(void*)message);
}
}
pthread_join(in_thread,NULL);
return 0;
}
void* send_message(void * args)
{
struct sockaddr_in sockaddr_out;
M_element message=(M_element)args;
int cfd=socket(AF_INET,SOCK_STREAM,0);
if(cfd==-1)
{
perror("send_socket");
exit(1);
}
sockaddr_out.sin_family=AF_INET;
sockaddr_out.sin_port=htons(9734);
printf("%s\n",message->target_IP);
sockaddr_out.sin_addr.s_addr=inet_addr(message->target_IP);
int ret=connect(cfd,(struct sockaddr *)&sockaddr_out,sizeof(sockaddr_out));
if(ret==-1)
{
perror("connect");
offline_message(message->target_IP,message->message);
exit(1);
}
if(write(cfd,message->message,strlen(message->message)+1)==-1)
{
perror("write");
exit(1);
}
close(cfd);
}
void* receive_message()
{
char buf[256];
char IP[256];
memset(IP,0,256);
int first_socket=socket(AF_INET,SOCK_STREAM,0);
if(first_socket==-1)
{
perror("socket");
exit(1);
}
struct sockaddr_in in_socketaddr;
in_socketaddr.sin_family=AF_INET;
in_socketaddr.sin_port=htons(9999);
in_socketaddr.sin_addr.s_addr=INADDR_ANY;
int ret=bind(first_socket,(struct sockaddr *)&in_socketaddr,sizeof(in_socketaddr));
if (ret==-1)
{
perror("bind");
exit(1);
}
ret=listen(first_socket,10);
if(ret==-1)
{
perror("listen");
exit(1);
}
int accept_socket;
while(1)
{
**//error occurs**
**accept_socket=accept(first_socket,NULL,NULL);**
printf("%d!",first_socket);
if(accept_socket==-1)
{
perror("accept");
exit(1);
}
int ret=read(accept_socket,buf,sizeof(buf));
close(accept_socket);
if(ret==-1)
{
perror("read1");
exit(1);
}
findIP(buf,IP);
**EnQueue(messages,buf,IP,IP);**
printf("%d!",first_socket);
}
close(first_socket);
}
我发送消息测试的appliaction,accecpt()效果很好
但我发送消息test111111,坏文件描述符时接受()调用发生;
我发现,当排队()调用first_socket的变化,但我不能找到一个解决方案..anyone可以帮助我,THX
I send message "test" to the appliaction , accecpt() works well but I send message "test111111" ,"bad file descriptor" occurs when accept() invokes; and I find the 'first_socket' changes when EnQueue() invokes,but i cant find a solution ..anyone can help me ,THX
推荐答案
看起来你有内存溢出。 4个字节的测试数据不超支这么多,但10倍率足以引起麻烦。
Looks like you have a memory overrun. 4 bytes of test data don't overrun so much, but 10 override enough to cause trouble.
最有可能的受害者是 first_socket
变量。如果它的覆盖,那么第二个接受
将得到错误的数量。结果
尝试打印 first_socket
之前每个接受
通话,看我是对的。
The most likely victim is the first_socket
variable. If it's overwritten, then the second accept
will get the wrong number.
Try to print first_socket
just before each accept
call, to see if I'm right.
编辑:mark40意见,排队
函数溢出其 A
变量
As mark40 comments, the EnQueue
function overruns its a
variable.
这篇关于Linux下C插座:"坏的文件描述符"发生在接受()调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!