1

我正在使用 linux/socket/tcp 编写一个发送/接收项目,我创建了一些线程来发送或接收消息,并使用全局队列来存储消息代码:

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);
}

我向应用程序发送消息“test”,accecpt() 运行良好,但我发送消息“test111111”,“错误文件描述符”在 accept() 调用时发生;当 EnQueue() 调用时,我发现“first_socket”发生了变化,但我找不到解决方案..任何人都可以帮助我,THX

4

1 回答 1

4

看起来你有内存溢出。4 字节的测试数据不会溢出这么多,但 10 字节的覆盖足以造成麻烦。

最有可能的受害者是first_socket变量。如果它被覆盖,那么第二个accept将得到错误的数字。
尝试first_socket在每次通话之前打印accept,看看我是否正确。

编辑:正如 mark40 评论,该EnQueue函数超出了它的a变量。

于 2012-07-10T15:30:12.743 回答