ECHO Server

尝试了一下在主进程只fork,子进程accept的结构,由于是测试用的小例子所以限定了用户数量为5个。

 

 

  1 #include <unistd.h>
  2 #include <pthread.h>
  3 #include <sys/wait.h>
  4 #include <sys/socket.h>
  5 #include <netinet/in.h>
  6 #include <arpa/inet.h>
  7 #include <signal.h>
  8 #include <errno.h>
  9 #include <stdlib.h>
 10 #include <stdio.h>
 11 #include <string.h>
 12 
 13 #define USERNUM 5
 14 #define SERVPORT 4322
 15 
 16 void
 17 rep_err(const char *msg)
 18 {
 19     fprintf(stderr, "%s\n", msg);
 20     perror("ECHOSERVER");
 21     exit(-1);
 22 }
 23 
 24 
 25 void
 26 dealchild(int signo)
 27 {
 28     pid_t pid;
 29     int   stat;
 30     while((pid = waitpid(-1, &stat, WNOHANG)) > 0);
 31         printf("Process %u is TERMINAL\n", pid);
 32     return;
 33 }
 34 
 35 void dofork(int);
 36 
 37 pthread_mutex_t MUTEX = PTHREAD_MUTEX_INITIALIZER;
 38 
 39 int
 40 main(int argc, char *argv[])
 41 {
 42     int               listenfd, err, i;
 43     pid_t             pid;
 44     struct sockaddr_in servaddr;
 45 
 46     if(signal(SIGCHLD, dealchild) == SIG_ERR)
 47         rep_err("SIGNAL");
 48 
 49     if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
 50         rep_err("SOCKET");
 51 
 52     memset(&servaddr, 0, sizeof(servaddr));
 53     servaddr.sin_family = AF_INET;
 54     servaddr.sin_port = htons(SERVPORT);
 55     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 56 
 57     if((err = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) < 0)
 58         rep_err("BIND");
 59 
 60     if((err = listen(listenfd, 128)) < 0)
 61         rep_err("LISTEN");
 62 
 63     for(i = 0; i < USERNUM; ++i)
 64     {
 65         if((pid = fork()) == 0)
 66         {
 67             dofork(listenfd);
 68         }
 69         else if(pid > 0)
 70         {}
 71         else
 72             rep_err("FORK");
 73     }
 74 
 75     pause();
 76 
 77     exit(0);
 78 }
 79 
 80 void
 81 dofork(int fd)
 82 {
 83     int                connfd, n;
 84     char               buffer[256];
 85     char               buf[128];
 86     struct sockaddr_in cli;
 87     socklen_t          clilen;
 88 
 89     clilen = sizeof(cli);
 90     pthread_mutex_lock(&MUTEX);
 91     if((connfd = accept(fd, (struct sockaddr *)&cli, &clilen)) <= 0)
 92         rep_err("ACCEPT");
 93     pthread_mutex_unlock(&MUTEX);
 94 
 95     snprintf(buffer, 256,
 96             "HELLO %s , FROM PORT : %d\n", 
 97             inet_ntop(AF_INET, &cli.sin_addr, buf, 128), 
 98             ntohs(cli.sin_port));
 99 
100     write(connfd, buffer, strlen(buffer));
101 
102         for(;;)
103         {
104 again:
105             if((n = read(connfd, buffer, 256)) < 0)
106             {
107                 if(errno == EINTR)
108                     goto again;
109                 else
110                     rep_err("READ");
111             }
112             write(connfd, buffer, n);
113         }
114 }

 

posted on 2013-04-16 16:45  Zirconi 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/Zirx/archive/2013/04/16/3024304.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
lwIP(Lightweight IP)是一个轻量级的开源TCP/IP协议栈,它被设计为可移植、可扩展和高度定制化,适用于各种嵌入式系统。其中,echo server是lwIP协议栈中比较基本的一个应用。 Echo server的作用是将接收到的数据原样返回给发送方。在lwIP中,echo server是由一个名为echod的应用程序实现的。下面,我将详细介绍lwIP echo server的实现流程。 1. 创建socket 首先,我们需要创建一个socket,用于监听客户端的连接请求。在lwIP中,socket是通过调用lwip_socket()函数创建的。例如: ``` int sock = lwip_socket(AF_INET, SOCK_STREAM, 0); ``` 其中,AF_INET表示IPv4地址族,SOCK_STREAM表示TCP协议。 2. 绑定IP地址和端口号 创建socket后,我们需要将其绑定到一个IP地址和端口号上,以便客户端能够连接到服务器。在lwIP中,可以通过调用lwip_bind()函数实现。例如: ``` struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(7); // Echo server默认端口号为7 addr.sin_addr.s_addr = htonl(INADDR_ANY); // 监听所有网络接口 lwip_bind(sock, (struct sockaddr *)&addr, sizeof(addr)); ``` 其中,INADDR_ANY表示监听所有网络接口。 3. 监听连接请求 绑定端口号后,我们需要开始监听连接请求。在lwIP中,可以通过调用lwip_listen()函数实现。例如: ``` lwip_listen(sock, 5); // 允许同时连接的客户端数量为5 ``` 4. 接受连接 当有客户端连接到服务器时,我们需要接受连接请求,并创建一个新的socket用于与该客户端通信。在lwIP中,可以通过调用lwip_accept()函数实现。例如: ``` struct sockaddr_in client_addr; int client_sock = lwip_accept(sock, (struct sockaddr *)&client_addr, sizeof(client_addr)); ``` 5. 接收数据 当与客户端建立连接后,我们需要等待客户端发送数据。在lwIP中,可以通过调用lwip_read()函数实现。例如: ``` char buf[1024]; int len = lwip_read(client_sock, buf, sizeof(buf)); ``` 6. 发送数据 接收到客户端的数据后,我们需要将其原样返回给客户端。在lwIP中,可以通过调用lwip_write()函数实现。例如: ``` lwip_write(client_sock, buf, len); ``` 7. 关闭socket 当通信结束后,我们需要关闭与客户端建立的socket。在lwIP中,可以通过调用lwip_close()函数实现。例如: ``` lwip_close(client_sock); ``` 8. 释放资源 最后,我们需要释放创建的socket资源。在lwIP中,可以通过调用lwip_shutdown()函数实现。例如: ``` lwip_shutdown(sock, SHUT_RDWR); ``` 以上就是lwIP echo server的实现流程。需要注意的是,echod应用程序是在一个单独的线程中运行的,它不断地等待客户端的连接请求,并在接收到数据后将其原样返回给客户端。如果有多个客户端连接到服务器,echod应用程序会为每个客户端创建一个新的socket,从而实现多客户端同时连接的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值