how to use threading and sockets in c correctly?

◇◆丶佛笑我妖孽 提交于 2020-07-09 14:06:14

问题


I created a simple chat app with threading and sockets, however my conn_1 can only send messages and conn_2 only receives messages. But they should do receiving and sending. I tried that the programm runs the two functions in the background, which are receiving and sending the messages to the other connection. Can some one help me? I dont know what I did wrong.

Source code:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>

#define PORT_CONN1 4444
#define PORT_CONN2 4445

char buf1[1024];
char buf2[1024];

int msg_1() {
  while(1) {
    recv(conn_1, &buf1, 1024, 0);
    send(conn_2, buf1, sizeof(buf1), 0);
  }
}

int msg_2() {
  while(1) {
    recv(conn_2, &buf2, 1024, 0);
    send(conn_1, buf2, sizeof(buf2), 0);
  }
}

int main() {
  int sockfd_1, sockfd_2, conn_1, conn_2;
  struct sockaddr_in host_addr, client_addr;
  socklen_t sin_size;
  int recv_length=1, ok=1;

  sockfd_1 = socket(PF_INET, SOCK_STREAM, 0);
  sockfd_2 = socket(PF_INET, SOCK_STREAM, 0);
  setsockopt(sockfd_1, SOL_SOCKET, SO_REUSEADDR, &ok, sizeof(int));
  setsockopt(sockfd_2, SOL_SOCKET, SO_REUSEADDR, &ok, sizeof(int));

  host_addr.sin_family = AF_INET;
  host_addr.sin_port = htons(PORT_CONN1);
  host_addr.sin_addr.s_addr = 0;
  memset(&(host_addr.sin_zero), "\0", 8);

  bind(sockfd_1, (struct sockaddr *)&host_addr, sizeof(struct sockaddr));

  host_addr.sin_family = AF_INET;
  host_addr.sin_port = htons(PORT_CONN2);
  host_addr.sin_addr.s_addr = 0;
  memset(&(host_addr.sin_zero), "\0", 8);

  bind(sockfd_2, (struct sockaddr *)&host_addr, sizeof(struct sockaddr));

  listen(sockfd_1, 5);
  listen(sockfd_2, 5);

  while(1) {
    pthread_t thread1, thread2;
    sin_size = sizeof(struct sockaddr_in);
    conn_1 = accept(sockfd_1, (struct sockaddr *)&client_addr, &sin_size);
    conn_2 = accept(sockfd_2, (struct sockaddr *)&client_addr, &sin_size);

    pthread_create(&thread1, NULL, msg_1, NULL);
    pthread_create(&thread2, NULL, msg_2, NULL);
    pthread_exit(NULL);

    close(conn_1);
    close(conn_2);
  }
}


回答1:


I dont know what I did wrong.

Some hints.

First your program cannot compile

  • in msg_1 and msg_2 you use the conn_1 and conn_2 which are undefined (they are local variables in main)
  • the second argument of memset must be an int specifying the byte used to set the block of memory, you give an array of char ("\0")
  • the signature of msg_1 and msg_2 are not compatible with thread_create

You want to exchange data between two threads through socket(s), you do not need to use two sockets for that, only one is enough because a socket is bi directional (contrarily with the pipes).

To have a socket you need a server and a client, the same thread cannot be both of them, accept blocks the thread until a client connects. In your program the main thread class accept but there is no client to connect, so you are definitively blocked.

The fact the end of main is in a while is quite obscure. This is also the case of pthread_exit(NULL); if you use that functions this is in the two threads but not in main.

Note the used socket is a stream, that means when you read on it you cannot suppose something about the number of bytes you get. This is the difference with the datagram.

So someone needs to be the server of your socket and someone else running in parallel must the a client. Because the socket will be used to exchange data between threads it seems natural one is the server and the other one the client. Note to use two additional threads is useless because your main thread will have nothing to do, so you can just have one additional thread rather than two.

To simplify I encourage you to do a first version where the main is the server and the only one additional thread is the client. Warning to not launch the additional thread too early nor too late, that means after the listen but before the accept.



来源:https://stackoverflow.com/questions/61364667/how-to-use-threading-and-sockets-in-c-correctly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!