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変数です。上書きされると、2番目acceptの番号は間違った番号になります。私が正しいかどうかを確認するために、各呼び出しの直前に
印刷してみてください。first_socketaccept

編集:mark40がコメントしているように、EnQueue関数はそのa変数をオーバーランします。

于 2012-07-10T15:30:12.743 に答える