【问题标题】:String with thread in tcp client / server in CC中tcp客户端/服务器中带有线程的字符串
【发布时间】:2012-10-04 17:32:51
【问题描述】:

我正在尝试用 C 语言开发一个应用程序来接收消息并在 TCP 中发送它。为此,我使用了 2 个线程:用于监听的服务器线程和用于发送它的客户端线程。

这里是服务器和主要功能:

void dostuff(int sock)
{
  int n;
  char buffer[256];

  bzero(buffer,256);
  n = read(sock,buffer,255);

  if (n < 0) error("ERROR reading from socket");
  else {
    pthread_t t_tcp_client;
    pthread_create(&t_tcp_client, NULL, tcp_client, buffer);
  }

  n = write(sock,"Message received",18);

  if (n < 0) error("ERROR writing to socket");
}

static void *tcp_server(void *p_data)
{
  int sockfd, newsockfd, pid;
  socklen_t clilen;
  struct sockaddr_in serv_addr, cli_addr;

  sockfd = socket(AF_INET, SOCK_STREAM, 0);

  if (sockfd < 0) error("ERROR opening socket");

  bzero((char *) &serv_addr, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(TCP_PORT);

  if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding");

  listen(sockfd,5);
  clilen = sizeof(cli_addr);

  while (1) {
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);

    if (newsockfd < 0) error("ERROR on accept");

    pid = fork();

    if (pid < 0) error("ERROR on fork");

    if (pid == 0) {
      close(sockfd);
      dostuff(newsockfd);
      exit(0);
    } else {
      close(newsockfd);
    }
  }
  close(sockfd);
  return 0;
}


int main (void)
{
  pthread_t t_tcp_server;
  pthread_create(&t_tcp_server, NULL, tcp_server, NULL);

  pthread_join(t_tcp_server, NULL);

  return 0;
}

还有客户端线程:

static void *tcp_client(void *p_data)
{
  if (p_data != NULL)
  {
    char const *message = p_data;

    printf("Message transmitted : %s\n", message);
  }

  return 0;
}

问题是客户端线程没有收到好字符,结果是:

消息传输:???~?

我认为问题出在以下行:n = read(sock,buffer,255);但我真的不明白为什么。

感谢您的帮助

【问题讨论】:

    标签: c multithreading tcp client-server


    【解决方案1】:
    static char buffer[256];
    
    void dostuff(int sock)
    {
       int n;
    
       bzero(buffer,256);
       n = read(sock,buffer,255);
       ...
    }
    

    使用套接字时要小心,一次读取可能无法为您提供等待消息的全部内容。

    在结构化消息的情况下,您定义的协议(您应该定义好)首先必须给出消息标识符,并且您阅读直到收到 sizeof( theSpecificMessage ),theSpecificMessage 由标识符标识。

    【讨论】:

      【解决方案2】:

      do_stuff 很可能在客户端线程工作之前就退出了。

      客户端线程使用堆栈分配的内存,然后在do_stuff 退出时被释放,并将被其他代码重用。

      解决方案是将堆分配的内存传递给客户端。如果是动态分配的,则后者需要在客户端完成工作后释放。

      【讨论】:

      • +1 是的,char buffer[256] 会被分配到栈上,当 dostuff() 返回时,它会被栈的其他用途改变。在静态外部 dostuff() 声明它。
      • 啊,太好了,当你评论 +1 时我变得不确定,最后我的答案再也看不到了,这让我觉得你改变了主意并 -1 回答了我的答案......@Aubin跨度>
      • 唯一的 -1 会导致 -2 的声誉(到目前为止还没有可见的声誉,幸运的是 ;-)。同一个人的 +1 后跟 -1 会导致 +-0 声望。后者是我虽然你一直在做的...... @Aubin 无论如何谢谢!
      猜你喜欢
      • 2019-04-18
      • 1970-01-01
      • 2014-03-04
      • 2012-12-12
      • 2015-08-29
      • 2017-10-11
      • 1970-01-01
      • 2015-12-01
      • 1970-01-01
      相关资源
      最近更新 更多