From 122a69f715acfe73963a2347cbb335e41bce944c Mon Sep 17 00:00:00 2001 From: Guangxiong Lin Date: Thu, 1 Dec 2022 16:08:38 +0800 Subject: Implement echo server with error handling Implement echo server with error handling Fix gitignore Implement an echo server with error handling --- .gitignore | 2 ++ Makefile | 8 ++++---- client.c | 33 ++++++++++++++++++++++++++++++++- common.c | 8 ++++++++ common.h | 1 + server.c | 37 ++++++++++++++++++++++++++++++++++--- 6 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 common.c create mode 100644 common.h diff --git a/.gitignore b/.gitignore index 5761abc..1c102fa 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ *.o +client +server diff --git a/Makefile b/Makefile index 7c005c9..eee72d1 100644 --- a/Makefile +++ b/Makefile @@ -10,8 +10,8 @@ clean: %.o: %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ -client: client.o - $(CC) -o $@ $< +client: client.o common.o + $(CC) -o $@ $^ -server: server.o - $(CC) -o $@ $< +server: server.o common.o + $(CC) -o $@ $^ diff --git a/client.c b/client.c index 82c35a6..9e3a421 100644 --- a/client.c +++ b/client.c @@ -1,11 +1,19 @@ #include #include #include +#include +#include +#include +#include + +#include "common.h" int main() { int sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) + panic("socket creation error"); struct sockaddr_in serv_addr; bzero(&serv_addr, sizeof(serv_addr)); @@ -13,5 +21,28 @@ main() serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); serv_addr.sin_port = htons(8888); - connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); + if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) + panic("socket connect error"); + + while (true) { + char buf[1024]; + bzero(&buf, sizeof(buf)); + scanf("%s", buf); + ssize_t n_write_bytes = write(sockfd, buf, sizeof(buf)); + if (n_write_bytes == -1) { + printf("socket already disconnected, cannot write any more!\n"); + break; + } + + ssize_t n_read_bytes = read(sockfd, buf, sizeof(buf)); + if (n_read_bytes > 0) { + printf("message from server: %s\n", buf); + } else if (n_read_bytes == 0) { + printf("server socket disconnected!\n"); + break; + } else if (n_read_bytes == -1) { + close(sockfd); + panic("socket read error"); + } + } } diff --git a/common.c b/common.c new file mode 100644 index 0000000..154e60d --- /dev/null +++ b/common.c @@ -0,0 +1,8 @@ +#include +#include + +void panic(const char *msg) +{ + perror(msg); + exit(EXIT_FAILURE); +} diff --git a/common.h b/common.h new file mode 100644 index 0000000..fbb7267 --- /dev/null +++ b/common.h @@ -0,0 +1 @@ +void panic(const char *); diff --git a/server.c b/server.c index 9e2fd5c..63f3062 100644 --- a/server.c +++ b/server.c @@ -1,11 +1,20 @@ #include #include #include -#include +#include +#include +#include +#include +#include +#include + +#include "common.h" int main() { int sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) + panic("socket creation error"); struct sockaddr_in serv_addr; bzero(&serv_addr, sizeof(serv_addr)); @@ -13,14 +22,36 @@ int main() serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); serv_addr.sin_port = htons(8888); - bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); + if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) + panic("socket bind error"); - listen(sockfd, SOMAXCONN); + if (listen(sockfd, SOMAXCONN) == -1) + panic("socket listen error"); struct sockaddr_in clnt_addr; socklen_t clnt_addr_len = sizeof(clnt_addr); bzero(&clnt_addr, sizeof(clnt_addr)); + int clnt_sockfd = accept(sockfd, (struct sockaddr *)&clnt_addr, &clnt_addr_len); + if (clnt_sockfd == -1) + panic("socket accept error"); printf("New client fd %d, ip: %s, port: %d\n", clnt_sockfd, inet_ntoa(clnt_addr.sin_addr), ntohs(clnt_addr.sin_port)); + + while (true) { + char buf[1024]; + bzero(&buf, sizeof(buf)); + ssize_t n_read_bytes = read(clnt_sockfd, buf, sizeof(buf)); + if (n_read_bytes > 0) { + printf("message from client fd %d: %s\n", clnt_sockfd, buf); + write(clnt_sockfd, buf, sizeof(buf)); + } else if (n_read_bytes == 0) { + printf("client fd %d disconnected\n", clnt_sockfd); + close(clnt_sockfd); + break; + } else if (n_read_bytes == -1) { + close(clnt_sockfd); + panic("socket read error"); + } + } } -- cgit v1.2.3