问题
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
andmsg_2
you use theconn_1
andconn_2
which are undefined (they are local variables inmain
) - 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
andmsg_2
are not compatible withthread_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