我正在尝试用 C 语言制作一个简单的 CLI 消息传递。我发现了套接字。 我编写了一个简单的程序,客户端可以编写一些消息,服务器在服务器端打印它 我尝试打开多个客户端,但它只接受一个客户端,
我想制作一个程序,其中许多客户端可以加入服务器而不是一个并写入一些消息,目前只有服务器在服务器端打印客户端消息,但是当其他客户端加入时 并发送消息 我希望客户能够看到其他客户消息 目前我有 服务器.c
/*
server.c
*/
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX 256
#define PORT 8080
int main() {
int socket_return, accept_return, bind_return, listen_return;
struct sockaddr_in server_address, peer_address;
// Creating socket
socket_return = socket(AF_INET, SOCK_STREAM, 0);
if (socket_return == -1) {
perror("socket creation failed\n");
return -1;
} else {
printf("socket created\n");
}
//empty the server address`
bzero(&server_address, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(PORT);
// binding socket
bind_return = bind(socket_return, (struct sockaddr *)&server_address, sizeof(server_address));
if (bind_return == -1) {
perror("binding failed\n");
close(socket_return);
return -1;
} else {
printf("binding done\n");
}
// listening the socket
listen_return = listen(socket_return, 5);
if (listen_return == -1) {
perror("listening failed");
close(socket_return);
return -1;
} else {
printf("server is listening...\n");
}
socklen_t peer_address_len = sizeof(peer_address);
// accept connection
accept_return = accept(socket_return, (struct sockaddr *)&peer_address, &peer_address_len);
if (accept_return == -1) {
perror("accepting failed\n");
close(socket_return);
return -1;
} else {
printf("connection accepted\n");
}
char msg[MAX];
while (1) {
bzero(msg, sizeof(msg));
// Read message
ssize_t bytes_read = read(accept_return, msg, sizeof(msg) );
if (bytes_read == 0) {
printf("client disconnected\n");
break;
} else if (bytes_read < 0) {
perror("failed to read message\n");
break;
}
//displaying client message
printf("From client: %s", msg);
}
// closing
close(accept_return);
close(socket_return);
return 0;
}
客户端.c
/*
client.c
*/
#include <stdio.h>
#include <strings.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX 256
#define PORT 8080
int main() {
int socket_return, connect_return;
struct sockaddr_in server_address;
// Creating socket
socket_return = socket(AF_INET, SOCK_STREAM, 0);
if (socket_return == -1) {
printf("socket creation failed\n");
return -1;
} else {
printf("socket created\n");
}
bzero(&server_address, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
server_address.sin_port = htons(PORT);
// Connecting the server
connect_return = connect(socket_return, (struct sockaddr *)&server_address, sizeof(server_address));
if (connect_return == -1) {
printf("connection failed\n");
close(socket_return);
return -1;
} else {
printf("connected to server\n");
}
char msg[MAX];
int i;
while (1) {
bzero(msg, sizeof(msg));
printf("Enter string: ");
i = 0;
while ((msg[i++] = getchar()) != '\n');
//when server detects the client message as 'exit' close the server
if ((strncmp(msg, "exit", 4)) == 0) {
printf("Exiting client\n");
close(socket_return);
break;
}
// sending message
write(socket_return, msg, sizeof(msg));
printf("You wrote %s\n",msg);
}
// close
close(socket_return);
return 0;
}
要同时接受和处理多个客户端,您需要使用多线程的概念,例如 POSIX 线程库(pthreads)。
服务器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#define PORT 8080
#define BUFFER_SIZE 1024
// Function to handle client communication
void *handle_client(void *client_socket) {
int sock = *(int *)client_socket;
char buffer[BUFFER_SIZE];
int n;
while ((n = recv(sock, buffer, sizeof(buffer) - 1, 0)) > 0) {
buffer[n] = '\0'; // Null-terminate the received data
printf("Client: %s\n", buffer);
// Echo the received message back to the client
send(sock, buffer, n, 0);
}
if (n == 0) {
printf("Client disconnected\n");
} else {
perror("recv");
}
close(sock);
free(client_socket);
pthread_exit(NULL);
}
int main() {
int server_fd, new_socket, *client_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
pthread_t thread_id;
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// Setting up the address structure
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Binding the socket
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// Listening for incoming connections
if (listen(server_fd, 3) < 0) {
perror("listen");
close(server_fd);
exit(EXIT_FAILURE);
}
printf("Server is listening on port %d\n", PORT);
while (1) {
// Accepting new client connection
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) {
perror("accept");
close(server_fd);
exit(EXIT_FAILURE);
}
// Allocating memory for client socket descriptor
client_socket = malloc(sizeof(int));
*client_socket = new_socket;
// Creating a new thread to handle the client
if (pthread_create(&thread_id, NULL, handle_client, (void *)client_socket) < 0) {
perror("pthread_create");
close(new_socket);
free(client_socket);
continue;
}
// Detaching the thread so that it can clean up after itself
pthread_detach(thread_id);
}
close(server_fd);
return 0;
}
客户
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int sock;
struct sockaddr_in server_address;
char buffer[BUFFER_SIZE];
char *message = "Hello from client";
// Creating socket
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket creation error");
exit(EXIT_FAILURE);
}
// Setting up the server address structure
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", &server_address.sin_addr) <= 0) {
perror("Invalid address / Address not supported");
close(sock);
exit(EXIT_FAILURE);
}
// Connecting to the server
if (connect(sock, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
perror("Connection failed");
close(sock);
exit(EXIT_FAILURE);
}
// Sending a message to the server
send(sock, message, strlen(message), 0);
printf("Message sent\n");
// Receiving a response from the server
int n = recv(sock, buffer, sizeof(buffer) - 1, 0);
if (n > 0) {
buffer[n] = '\0'; // Null-terminate the received data
printf("Server: %s\n", buffer);
} else {
perror("recv");
}
close(sock);
return 0;
}