IO多路复用服务器 -- 实现字符回射
服务器端
/*************************************************************************
* File Name: select.c
* Author: Chen WenKe
* Email: chenwenke666@gmail.com
* Blog: https://caotanxiaoke.github.io
* Created Time: Mon 19 Jun 2017 03:42:26 AM PDT
*
* Description:
基于 IO 多路复用的回射 客户端-服务器。
************************************************************************/
#include "csapp.h"
void echo(int connfd);
void command(void);
int main(int argc, char **argv)
{
int listenfd, connfd, port;
socklen_t clientlen = sizeof(struct sockaddr_in);
struct sockaddr_in clientaddr;
fd_set read_set, ready_set;
if (argc != 2)
{
fprintf(stderr, "usage: %s <port>\n", argv[0]);
exit(0);
}
port = atoi(argv[1]);
listenfd = Open_listenfd(port);
FD_ZERO(&read_set); // clear the read set
FD_SET(STDIN_FILENO, &read_set); // Add stdin to read set
FD_SET(listenfd, &read_set); // Add listenfd to read set
while(1)
{
ready_set = read_set;
Select(listenfd+1, &ready_set, NULL, NULL, NULL);
if (FD_ISSET(STDIN_FILENO, &ready_set))
command(); // Read command line from stdin
if (FD_ISSET(listenfd, &ready_set))
{
connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
echo(connfd);
Close(connfd);
}
}
}
void command(void)
{
char buf[MAXLINE];
if (!Fgets(buf, MAXLINE, stdin))
exit(0); // EOF
printf("%s", buf); // Process the input command.
}
void echo(int connfd)
{
int n;
char buf[MAXLINE];
rio_t rio;
Rio_readinitb(&rio, connfd);
while (( n == Rio_readlineb(&rio, buf, MAXLINE)) != 0)
{
printf("server received %d bytes\n", n);
Rio_writen(connfd, buf, n);
}
}
客户端
/*************************************************************************
* File Name: echoclient.c
* Author: Chen WenKe
* Email: chenwenke666@gmail.com
* Blog: https://caotanxiaoke.github.io
* Created Time: Sun 18 Jun 2017 08:00:49 PM PDT
*
* Description:
************************************************************************/
#include "csapp.h"
int main(int argc, char **argv)
{
int clientfd, port;
char *host, buf[MAXLINE];
rio_t rio;
if (argc != 3)
{
fprintf(stderr, "usage: %s <host> <port>\n", argv[0]);
exit(0);
}
host = argv[1];
port = atoi(argv[2]);
clientfd = Open_clientfd(host, port);
Rio_readinitb(&rio, clientfd);
while (Fgets(buf, MAXLINE, stdin) != NULL)
{
Rio_writen(clientfd, buf, strlen(buf));
Fputs(buf, stdout);
}
Close(clientfd);
exit(0);
}
上面代码中所使用的头文件及编译方法