实现迭代型的echo服务器

    xiaoxiao2025-06-03  88

    文章目录

    Socket服务器设计实现迭代型的echo服务器 代码仓库地址

    Socket服务器设计

    ​ 对于使用socket的网络服务器端程序,有两种常见的设计方式:

    迭代式:服务器每次只处理一个客户端,只有当完全处理完一个客户端的请求后才会去处理下一个客户端并发型:能够同时处理单个客户端的请求

    实现迭代型的echo服务器

    #include <syslog.h> #include <sys/stat.h> #include <fcntl.h> #include "sys_tem.h" //< 创建迭代型 echo 服务器 #define BD_NO_CHDIR 01 /* Don't chdir("/") */ #define BD_NO_CLOSE_FILES 02 /* Don't close all open files */ #define BD_NO_REOPEN_STD_FDS 04 /* Don't reopen stdin, stdout, and stderr to /dev/null */ #define BD_NO_UMASK0 010 /* Don't do a umask(0) */ #define BD_MAX_CLOSE 8192 /* Maximum file descriptors to close if sysconf(_SC_OPEN_MAX) is indeterminate */ int becomeDaemon(int flags); //< 调用会使一个程序变成守护进程 int becomeDaemon(int flags) { int maxfd, fd; switch (fork()) { /* Become background process */ case -1: return -1; case 0: break; /* Child falls through... */ default: _exit(EXIT_SUCCESS); /* while parent terminates */ } if (setsid() == -1) /* Become leader of new session */ return -1; switch (fork()) { /* Ensure we are not session leader */ case -1: return -1; case 0: break; default: _exit(EXIT_SUCCESS); } if (!(flags & BD_NO_UMASK0)) umask(0); /* Clear file mode creation mask */ if (!(flags & BD_NO_CHDIR)) chdir("/"); /* Change to root directory */ if (!(flags & BD_NO_CLOSE_FILES)) { /* Close all open files */ maxfd = sysconf(_SC_OPEN_MAX); if (maxfd == -1) /* Limit is indeterminate... */ maxfd = BD_MAX_CLOSE; /* so take a guess */ for (fd = 0; fd < maxfd; fd++) close(fd); } if (!(flags & BD_NO_REOPEN_STD_FDS)) { close(STDIN_FILENO); /* Reopen standard fd's to /dev/null */ fd = open("/dev/null", O_RDWR); if (fd != STDIN_FILENO) /* 'fd' should be 0 */ return -1; if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO) return -1; if (dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) return -1; } return 0; } #define SERVICE "echo" #define BUF_SIZE 500 #define IS_ADDR_STR_LEN 4096 int main(int argc, char *argv[]) { int sfd; ssize_t numRead; socklen_t len; struct sockaddr_storage claddr; char buf[BUF_SIZE]; char addrStr[IS_ADDR_STR_LEN]; //< 将该进程变成守护进程 if (becomeDaemon(0) == -1) perror("becomeDaemon"); //< 创建一个socket 成功返回 0 失败返回-1 sfd = inetBind(SERVICE, SOCK_DGRAM, NULL); if (sfd == -1) { //< 创建socket失败,记录一下日志 syslog(LOG_ERR, "Could not create server socket (%s)", strerror(errno)); exit(EXIT_FAILURE); } /* Receive datagrams and return copies to senders */ //< 收到之后,数收到的数据进行处理,并将原始数据回显的方式给发送者 for (;;) { len = sizeof(struct sockaddr_storage); numRead = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *) &claddr, &len); if (numRead == -1) perror("recvfrom"); if (sendto(sfd, buf, numRead, 0, (struct sockaddr *) &claddr, len) != numRead) syslog(LOG_WARNING, "Error echoing response to %s (%s)", inetAddressStr((struct sockaddr *) &claddr, len, addrStr, IS_ADDR_STR_LEN), strerror(errno)); } }

    最新回复(0)