版权声明: https://blog.csdn.net/zl6481033/article/details/86242035
1、客户端
echo客户端,在和服务器连接以后,客户端应该进入一个循环,反复从标准输入读取文本行,发送文本行给服务器,从服务器读取回送的行,并输出结果到标准输出。当fgets在标准输入上遇到EOF时,或者因为用户在键盘上输入ctrl+D,或者在遇到一个重定向的输入文件中用尽了所有的文本行时,循环截止。
//CSAPP中的一些辅助函数的定义
#include "csapp.h"
int main(int argc, char **argv)
{
int clientfd, port;
char *host, buf[MAXLINE];
rio_t rio;
// 客户端需要传进参数,IP地址和端口
if (argc != 3)
{
fprintf(stderr, "usage: %s <host> <port>\n", argv[0]);
exit(0);
}
host = argv[1];
//将字符串转为int,书上没有转换是错的
port = atoi(argv[2]);
//打开
clientfd = Open_clientfd(host, port);
//初始化RIO读写
Rio_readinitb(&rio, clientfd);
while (Fgets(buf, MAXLINE, stdin) != NULL)
{
Rio_writen(clientfd, buf, strlen(buf));
Rio_readlineb(&rio, buf, MAXLINE);
Fputs(buf, stdout);
}
Close(clientfd); //line:netp:echoclient:close
exit(0);
}
2、服务器
服务器主程序,打开监听描述符,进入循环,等待一个来自客户端的连接请求,输出已连接的客户端域名和IP地址,并调用echo函数为这个客户端服务,在echo程序返回之后,主程序关闭已连接的描述符,一旦客户端和服务器都关闭了他们各自的描述符,连接终止。
#include "csapp.h"
//服务器为客户端服务函数
void echo(int connfd);
int main(int argc, char **argv)
{
int listenfd, connfd, port, clientlen;
struct sockaddr_in clientaddr;
struct hostent *hp;
char *haddrp;
//需要传入一个端口号
if (argc != 2)
{
fprintf(stderr, "usage: %s <port>\n", argv[0]);
exit(0);
}
//字符串转换为int
port = atoi(argv[1]);
//打开一个监听描述符
listenfd = Open_listenfd(port);
while (1)
{
clientlen = sizeof(clientaddr);
// 服务器通过调用accept函数来等待来自客户端的连接请求
connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
/* determine the domain name and IP address of the client */
hp = Gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr,
sizeof(clientaddr.sin_addr.s_addr), AF_INET);
haddrp = inet_ntoa(clientaddr.sin_addr);
printf("server connected to %s (%s)\n", hp->h_name, haddrp);
echo(connfd);
Close(connfd);
}
exit(0);
}
//服务函数
void echo(int connfd)
{
size_t n;
char buf[MAXLINE];
rio_t rio;
Rio_readinitb(&rio, connfd);
while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0)
{ //line:netp:echo:eof
printf("server received %d bytes\n", n);
Rio_writen(connfd, buf, n);
}
}
3、结果
客户端发送接收到服务器回显。
服务器显示接收到的数据大小。
这里是简单的一个echo服务器一次只能一个客户端,这种类型的服务器一次一个的在客户端间迭代,称为迭代服务器,如果需要建立更复杂的并发的服务器,他能够同时处理多个客户端。