C 中的 ATOI 与服务器/客户端 GMS 应用程序中的其他字符串混淆

问题描述 投票:0回答:1

您好,我们正在尝试进行 GMS 服务器/客户端聊天。 我们在这部分代码上使用 atoi 时遇到问题

unserialize_tcp(buffer,&type, &grpname, &member_name, &received_addr, &received_port);
printf("1%s %s %s\n", grpname, member_name, received_addr);
addr = atoi(received_addr);
client.sin_addr.s_addr = addr;
client.sin_port = received_port;
printf("2%s %s \n", grpname, member_name);

输出是这样的 正如你所看到的,在我们使用 atoi 后,成员名称就失去了原来的值

Succesfully created RECEIVER WORKER and SOCKET WORKER 

Available options
     type 'exit' to close gms  
BEFORE
AFTER
BEFORE
New Client socket 4 stored at index 0
packet 0_omada_onoma_16777343_26385
1omada onoma 16777343
2omada @���x 
3omada @���x 
4omada @���x 
Group omada just got a new member @���x 
We didn't notify every member of the group  about the new member

这是unserialize_tcp函数

void unserialize_tcp(char* message, type_t *type, char** grpname, char** member_name, char** received_addr, int* received_port) {

    char msg[TCP_PACKET] = {'\0'};
    char *saveptr;
    char *ptr = message;
    char *delim = "_";
    int i;
    for (i = 0; ptr[i]; ptr[i] == '_' ? i++ : *ptr++);
    if (i != 4) {
        printf("Message corrupted\n");
        return;
    }
    strcpy(msg, message);
    *type = atoi(strtok_r(msg, delim, &saveptr));
    *grpname = strtok_r(NULL, delim, &saveptr);
    *member_name = strtok_r(NULL, delim, &saveptr);
    *received_addr = strtok_r(NULL, delim, &saveptr);
    *received_port = atoi(strtok_r(NULL, delim, &saveptr));
    

}

这就是atoi问题产生的receive_worker线程


void *gms_receive_worker(void *args) {
  int i;
  char buffer[TCP_PACKET];
  char *grpname = (char*)calloc(16, sizeof(char));
  char* member_name = (char*)calloc(16, sizeof(char));
  type_t type ;
  char* received_addr = (char*)calloc(LENGTH_MSG, sizeof(char));
  char *msg;
  msg = (char*) malloc(sizeof(char)*TCP_PACKET);
  int received_port, addr;
  
  struct sockaddr_in client;
  while(!flag) {
    for (i=0; i< MAX_CLIENTS; i++) {
      memset(buffer, '\0',sizeof(buffer));
      if (recv(client_sockets[i], (char*)buffer, TCP_PACKET, MSG_WAITALL) < 0 ) {
            continue;
      }
      
      if(strlen(buffer) > 0) {
        printf("packet %s\n", buffer);
        unserialize_tcp(buffer,&type, &grpname, &member_name, &received_addr, &received_port);
        printf("1%s %s %s\n", grpname, member_name, received_addr);
        addr = atoi(received_addr);
        client.sin_addr.s_addr = addr;
        client.sin_port = received_port;
         printf("2%s %s \n", grpname, member_name);
        if (type == EXIT_TCP_SOCKET) {
          printf(BOLDRED"Client exited and the socket %d just closed\n"RESET, client_sockets[i]);
          client_sockets[i] = 0;
          continue;
        }
        else if (type == GROUP_JOIN) {
          printf("3%s %s \n", grpname, member_name);
          if (search_gms_list(list, grpname, member_name) != NULL) {
            msg = serialize_tcp(GROUP_REJECT_MEMBER, grpname, member_name, received_addr, received_port);
            if(send(client_sockets[i], (const char *)msg, TCP_PACKET, MSG_NOSIGNAL) < 0 ) {
                printf(BOLDRED"Failed inside group join\n"RESET);
                exit(1);
            }
            continue;
          }
           printf("4%s %s \n", grpname, member_name);
          printf(BOLDRED"Group %s just got a new member %s \n"RESET, grpname, member_name);
          
          add_gms_list(list, grpname, member_name, client, client_sockets[i]);
          msg = serialize_tcp(GROUP_SOMEONE_JOINED, grpname, member_name, received_addr, received_port);
            
          if (gms_sender_worker(grpname,member_name, msg) == 1) {
            printf(CYAN"We notified every member of the group %s about the new member\n"RESET, grpname);
            continue;
          }
          else{
            printf(CYAN"We didn't notify every member of the group %s about the new member\n"RESET, grpname);
            continue;
          }
            
        }
        else if (type == GROUP_LEAVE ) {
          if (search_gms_list(list, grpname, member_name) == NULL) {
            msg = serialize_tcp(LEAVE_FAILED, grpname, member_name, received_addr, received_port);
            if(send(client_sockets[i], (const char *)msg, TCP_PACKET, MSG_NOSIGNAL) < 0 ) {
                printf(BOLDRED"Failed inside group join\n"RESET);
                exit(1);
            }
            continue;
          }
          printf(BOLDRED"Group %s lost the member %s \n"RESET, grpname, member_name);

          delete_gms_list(list, grpname, member_name, client);
          msg = serialize_tcp(GROUP_SOMEONE_LEFT, grpname, member_name, received_addr, received_port);
            
          if (gms_sender_worker(grpname,member_name, msg) == 1) {
            printf(CYAN"We notified every member of the group %s about the member that left\n"RESET, grpname);
            continue;
          }
          else{
            printf(CYAN"We didn't notify every member of the group %s about the member that left\n"RESET, grpname);
            continue;
          }
        }
        else{
          printf(BOLDRED"You are not supposed to see this \n"RESET);
        }
      }
    }
  }
  free(grpname);
  free(member_name);
  free(received_addr);
  free(msg);
  

  pthread_exit(NULL);
}


当我们将 atoi 放入注释中时,member_name 保留其原始值 这个问题很奇怪,我们找不到解决方案。 任何想法表示赞赏,谢谢!

我们没想到 atoi 会破坏另一个字符串的值,我们希望看到相同的打印语句。但我们不

c server client distributed-system atoi
1个回答
0
投票

这是你的问题(至少是其中一个),有十几行:

int main()
{
    char* foo = malloc(100);
    bar(&foo);
}

void bar(char** arg)
{
   char example[] = "this is an example";
   *arg = strtok(example, " ");
}

你现在能找出问题所在吗?

还是没有?

让我们手动内联

bar

int main()
{
    char* foo = malloc(100);
    {
       char example[] = "this is an example";
       *foo = strtok(example, " ");
    }
}

您分配一个缓冲区以便将数据复制到其中。不是为了立即覆盖指向所述缓冲区的唯一现有指针,永远丢失分配的内存,并在进程中创建一个悬空指针(有关更多说明,请参阅this)。

你需要的其实就是这个

int main()
{
    char* foo = malloc(100);
    bar(foo); // note no &
}

void bar(char* arg) // note one star
{
   char example[] = "this is an example";
   strcpy(arg, strtok(example, " ")); // note no `=`
}
© www.soinside.com 2019 - 2024. All rights reserved.