gpt4 book ai didi

c - C 中的多线程套接字

转载 作者:行者123 更新时间:2023-11-30 16:12:39 25 4
gpt4 key购买 nike

我正在尝试编辑我之前创建客户端和服务器套接字时编写的代码,允许客户端向服务器发送消息,服务器以“我明白了..”+消息进行响应。这很有效,但接下来的步骤是我遇到的问题。

我希望能够连续发送消息,直到客户端说“退出”,并支持多个客户端。

我拥有的适用于一对一客户端/服务器通信的代码:

服务器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

void error(const char *msg) {
perror(msg);
exit(1);
}

int main(int argc, char *argv[]) {
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n; // return value for the read() and write() calls

// gcc server.c -o server
// ./server 8080
// Pass in Port # or pass error
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}

sockfd = socket(AF_INET, SOCK_STREAM, 0);
// Error if Socket Call fails
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr)); // Set all values in a buffer to zero, args: pointer to buffer, size of buffer, sets serv_addr ot zero
portno = atoi(argv[1]); // Port number listens for connections
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);

// Binds socket to an address
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");

// Listens to the socket for connections
listen(sockfd,5);

clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");

bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);


n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
close(newsockfd);
close(sockfd);
return 0;
}

客户:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>



void error(const char *msg) {
perror(msg);
exit(0);
}

int main(int argc, char *argv[]) {
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
// gcc client.c -o client
// ./client localhost 8080
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");

server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
// Error Connecting to the server
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");

printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);

close(sockfd);
return 0;
}

我的想法是服务器文件有一个 while 循环:

while(buffer != "EXIT"){
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);


n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
close(newsockfd);
close(sockfd);
}

但它只在一个客户端和服务器之间进行一次交互。

最佳答案

这似乎不是一个多线程应用程序。我在这里看到的基本问题是您的服务器尚未准备好同时接受多个客户端。 while循环只是将读和写一一处理。

需要实现的基本逻辑是:

1.) 使用“accept”函数接受新的连接请求。

2.) 创建一个新线程(使用 pthread_create)来读取和写入同一连接请求。并同时准备好来自“accept”函数的新连接请求。

3.) 按照步骤 1 和 2 保持发送和接收流程,直到出现“EXIT”。

关于c - C 中的多线程套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58279573/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com