commit f61f53d80dd1e04a571b260324576c11b0d9d959
parent 385af01b7ea5b08bc7d03841c17b156afaa9401f
Author: evenfri <evenfri256@gmail.com>
Date: Fri, 28 Aug 2026 01:12:15 +0800
fixes
Diffstat:
| M | client.c | | | 8 | +++++--- |
| M | server.c | | | 89 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
2 files changed, 76 insertions(+), 21 deletions(-)
diff --git a/client.c b/client.c
@@ -37,7 +37,7 @@ int main(int argc, char *argv[]) {
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
- if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) {
+ if (inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr) != 1) {
fprintf(stderr, "invalid address\n");
close(fd);
return 1;
@@ -64,7 +64,8 @@ int main(int argc, char *argv[]) {
if (result == -1) {
perror("poll");
- break;
+ close(fd);
+ return 1;
}
/*
@@ -75,7 +76,8 @@ int main(int argc, char *argv[]) {
if (n == -1) {
perror("recv");
- break;
+ close(fd);
+ return 1;
}
if (n == 0) {
diff --git a/server.c b/server.c
@@ -2,6 +2,8 @@
#include <string.h>
#include <unistd.h>
#include <poll.h>
+#include <signal.h>
+#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -9,6 +11,18 @@
#define MAX_CLIENTS 16
#define BUFFER_SIZE 1024
+void remove_client(struct pollfd *fds, int *client_count, int index) {
+ int i;
+
+ close(fds[index].fd);
+
+ for (i = index; i < *client_count; i++) {
+ fds[i] = fds[i + 1];
+ }
+
+ (*client_count)--;
+}
+
int main() {
int server_fd;
int client_fd;
@@ -17,16 +31,33 @@ int main() {
int j;
int n;
int result;
+ int opt;
struct sockaddr_in addr;
struct pollfd fds[MAX_CLIENTS + 1];
char buffer[BUFFER_SIZE];
+ signal(SIGPIPE, SIG_IGN);
+
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("socket");
return 1;
}
+ opt = 1;
+
+ if (setsockopt(
+ server_fd,
+ SOL_SOCKET,
+ SO_REUSEADDR,
+ &opt,
+ sizeof(opt)
+ ) == -1) {
+ perror("setsockopt");
+ close(server_fd);
+ return 1;
+ }
+
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
@@ -58,6 +89,10 @@ int main() {
result = poll(fds, client_count + 1, -1);
if (result == -1) {
+ if (errno == EINTR) {
+ continue;
+ }
+
perror("poll");
break;
}
@@ -87,22 +122,37 @@ int main() {
* Existing clients.
*/
for (i = 1; i <= client_count; i++) {
+ /*
+ * Error or disconnect.
+ */
+ if (fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) {
+ printf("client %d disconnected\n", fds[i].fd);
+
+ remove_client(fds, &client_count, i);
+ i--;
+
+ continue;
+ }
+
if (!(fds[i].revents & POLLIN)) {
continue;
}
- n = recv(fds[i].fd, buffer, sizeof(buffer), 0);
+ n = recv(
+ fds[i].fd,
+ buffer,
+ sizeof(buffer),
+ 0
+ );
if (n == -1) {
- perror("recv");
-
- close(fds[i].fd);
-
- for (j = i; j < client_count; j++) {
- fds[j] = fds[j + 1];
+ if (errno == EINTR) {
+ continue;
}
- client_count--;
+ perror("recv");
+
+ remove_client(fds, &client_count, i);
i--;
continue;
@@ -111,29 +161,32 @@ int main() {
if (n == 0) {
printf("client %d disconnected\n", fds[i].fd);
- close(fds[i].fd);
-
- for (j = i; j < client_count; j++) {
- fds[j] = fds[j + 1];
- }
-
- client_count--;
+ remove_client(fds, &client_count, i);
i--;
continue;
}
+ printf(
+ "client %d sent %d bytes\n",
+ fds[i].fd,
+ n
+ );
+
/*
* Broadcast.
*/
- printf("client %d sent %d bytes\n", fds[i].fd, n);
-
for (j = 1; j <= client_count; j++) {
if (j == i) {
continue;
}
- if (send(fds[j].fd, buffer, n, 0) == -1) {
+ if (send(
+ fds[j].fd,
+ buffer,
+ n,
+ MSG_NOSIGNAL
+ ) == -1) {
perror("send");
}
}