什么是echo服务器

什么是echo服务器,第1张

英文原义是Echo Protocol,中文释义是应答协议,它主要用于调试和检稿滑测中。

它可以基于TCP协议,服务器就在TCP端口七检测有无消息,如果使用UDP协议,基本过程和TCP一样,检测的端口也是七。他也是路由也是网络中最常用的数据纤巧包,可以通过发送echo包知道当前的毁敬键连接节点有那些路径,并且通过往返时间能得出路径长度。

先 netstat -nl | grep 9999 看看是否有进程已经在9999端樱坦辩口侦听,如果有,kill掉那个脊缺进程,或者改用其他端口。然后,用下面修改过的代信蠢码。

至于调试,很简单, 用 gdb 调试 server端即可,由于你是用fork子进程来处理新连接,需要在gdb里 set follow-fork-mode child。具体自己去学gdb吧。或者你改成不用fork,单进程处理,比如用 select/pthread 等手段,这样也比较好调试。

#include <stdio.h>

#include <stdlib.h>

#include <sys/socket.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <errno.h>

#include <strings.h>

#include <unistd.h>

#define MAXLINE 4096

void echo_write(int sockfd)

ssize_t written(int sockfd, const void *buf, size_t nbytes)

ssize_t readline(int sockfd, void *buf, int maxlen)

int main(int argc, char **argv) {

int listenfd, connfd, len

pid_t pid

struct sockaddr_in servaddr, cliaddr

char bufaddr[MAXLINE]

listenfd = socket(AF_INET, SOCK_STREAM, 0)

servaddr.sin_family = AF_INET

servaddr.sin_addr.s_addr = htonl(INADDR_ANY)

servaddr.sin_port = htons(9999)

bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr))

listen(listenfd, 100)

for( ) {

len = sizeof(cliaddr)

connfd = accept(listenfd, (struct sockaddr*) &cliaddr, &len)

printf("accept ok\n")

if( (pid = fork()) == 0) {

printf("connection from %s : %d\n",

inet_ntop(AF_INET, &cliaddr.sin_addr, bufaddr, sizeof(bufaddr)),

ntohs(cliaddr.sin_port))

close(listenfd)

printf("echo_write start.\n")

echo_write(connfd)

close(connfd)

exit(0)

}

close(connfd)

}

exit(0)

}

void echo_write(int sockfd) {

char buf[MAXLINE]

ssize_t n

printf("let's read.\n")

again:

printf("begin read.\n")

while( (n = readline(sockfd, buf, MAXLINE)) >0) {

printf("n: %d\n", n)

written(sockfd, buf, n)

printf("written ok.\n")

}

if(n <0 &&errno == EINTR) {

goto again

} else if(n <0) {

printf("read error")

}

}

ssize_t readline(int sockfd, void *buf, int maxlen) {

char *ptr, c

ssize_t n, rc

ptr = buf

for(n = 1n <maxlenn++) {

again:

if( (rc = read(sockfd, &c, 1)) == 1) {

*ptr++ = c

if(c == '\n') {

break

}

} else if(rc == 0) {

*ptr = 0

return n - 1

} else {

if(rc <0 &&errno == EINTR) {

goto again

}

return -1

}

}

*ptr = 0

return n

}

ssize_t written(int sockfd, const void *buf, size_t nbytes) {

const char *buf_ptr

size_t nleft = nbytes

ssize_t nwritten

buf_ptr = buf

while(nleft >0) {

if( (nwritten = write(sockfd, buf_ptr, nleft)) <= 0) {

if(nwritten <0 &&errno == EINTR) {

nwritten = 0

} else {

return -1

}

}

nleft -= nwritten

buf_ptr += nwritten

}

return nbytes

}

反复从标准输入读取文本行,发送文谈宽本行给服务器。

从服务器读取回送的行,并输出结果到标准输出。当fgets在标准输入上遇到EOF时,或者因为用户在键盘含纯亮上输入ctrl加D,或者在遇到一个重定向的输入文件中用尽了所有的文本行时,循环截止。

服务器主程序,打开监听描述符,进入循环,等待一个来自客户端的连接请求,输出已连接的客户端域名和IP地址,并调裤耐用echo函数为这个客户端服务。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12538542.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存