linux系统echo函数,Linux下echo与time服务的程序实现

一、针对ECHO服务的TCP客户软件的实现

1.网络拓扑结构:

a699c13047eb64e03724f49cfab485e7.png

2.源码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define LINELEN 128

extern int errno;

int TCPecho(const char *host, const char *service);

int errexit(const char *format,...);

int connectsock(const char *host, const char *service, const char *transport );

int connectTCP(const char *host, const char *service);

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

char *host= "localhost";

char *service= "echo";

switch(argc){

case 1:

host = "localhost";

break;

case 3:

service = argv[2];

case 2:

host=argv[1];

break;

default:

fprintf(stderr,"usage:TCPecho[host[port]]\n");

exit(1);

}

TCPecho(host,service);

exit(0);

}

int TCPecho(const char *host,const char *service){

char buf[LINELEN+1];

int s,n;

int outchars, inchars;

s=connectTCP(host, service);

while(fgets(buf,sizeof(buf),stdin)){

buf[LINELEN]='\0';

outchars=strlen(buf);

(void)write(s,buf,outchars);

for(inchars=0;inchars

n=read(s,&buf[inchars],outchars-inchars);

if(n<0)

errexit("socker read failed: %s\n",strerror(errno));

}

fputs(buf,stdout);

}

}

int errexit(const char *format,...){

va_list arg;

va_start(arg, format);

vfprintf(stderr,format,arg);

va_end(arg);

exit(1);

}

int connectsock(const char *host, const char *service, const char *transport )

/*

* Arguments:

*      host      - name of host to which connection is desired

*      service  - service associated with the desired port

*      transport - name of transport protocol to use ("tcp" or "udp")

*/

{

struct hostent  *phe;  /* pointer to host information entry    */

struct servent  *pse;  /* pointer to service information entry */

struct protoent *ppe;  /* pointer to protocol information entry*/

struct sockaddr_in sin; /* an Internet endpoint address    */

int s, type;    /* socket descriptor and socket type    */

memset(&sin, 0, sizeof(sin));

sin.sin_family = AF_INET;

/* Map service name to port number */

if ( pse = getservbyname(service, transport) )

sin.sin_port = pse->s_port;

else if ((sin.sin_port=htons((unsigned short)atoi(service))) == 0)

errexit("can't get \"%s\" service entry\n", service);

/* Map host name to IP address, allowing for dotted decimal */

if ( phe = gethostbyname(host) )

memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);

else if ( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE )

errexit("can't get \"%s\" host entry\n", host);

/* Map transport protocol name to protocol number */

if ( (ppe = getprotobyname(transport)) == 0)

errexit("can't get \"%s\" protocol entry\n", transport);

/* Use protocol to choose a socket type */

if (strcmp(transport, "udp") == 0)

type = SOCK_DGRAM;

else

type = SOCK_STREAM;

/* Allocate a socket */

s = socket(PF_INET, type, ppe->p_proto);

if (s < 0)

errexit("can't create socket: %s\n", strerror(errno));

/* Connect the socket */

if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)

errexit("can't connect to %s.%s: %s\n", host, service,

strerror(errno));

return s;

}

int connectTCP(const char *host, const char *service){

return connectsock(host,service,"tcp");

}

二、针对echo服务的并发的面向连接的服务器软件的实现

1.网络拓扑结构:

f51b5995061ec0719116378e45004d33.png

2.源码:

#define _USE_BSD

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define QLEN 32

#define BUFSIZE 4096

extern int errno;

unsigned short portbase = 0;

void reaper(int);

int TCPechod(int fd);

int errexit(const char *format,...);

int passivesock(const char *service, const char *transport, int qlen);

int passiveTCP(const char *service,int qlen);

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

char *service= "echo";

struct sockaddr_in fsin;

unsigned int alen;

int msock,ssock;

switch(argc){

case 1:

break;

case 2:

service=argv[1];

break;

default:

errexit("usage: TCPechod [port]\n");

}

msock=passiveTCP(service,QLEN);

(void)signal(SIGCHLD,(__sighandler_t)QLEN);

while(1){

alen=sizeof(fsin);

ssock=accept(msock,(struct sockaddr *)&fsin,&alen);

if(ssock<0){

if(errno==EINTR)    continue;

errexit("accept: %s\n",strerror(errno));

}

switch(fork()){

case 0:

(void)close(msock);

exit(TCPechod(ssock));

default:

(void)close(ssock);

break;

case -1:

errexit("fork: %s\n",strerror(errno));

}

}

}

void reaper(int sig){

int status;

while(wait3(&status,WNOHANG,(struct rusage *)0)>=0) ;

}

int TCPechod(int fd){

char buf[BUFSIZ];

int cc;

while(cc=read(fd,buf,sizeof(buf))){

if(cc<0)

errexit("echo read: %s\n",strerror(errno));

if(write(fd,buf,cc)<0)

errexit("echo write: %s\n",strerror(errno));

}

return 0;

}

int errexit(const char *format,...){

va_list arg;

va_start(arg, format);

vfprintf(stderr,format,arg);

va_end(arg);

exit(1);

}

int passivesock(const char *service, const char *transport, int qlen)

/*

* Arguments:

*      service  - service associated with the desired port

*      transport - transport protocol to use ("tcp" or "udp")

*      qlen      - maximum server request queue length

*/

{

struct servent*pse;/* pointer to service information entry*/

struct protoent *ppe;/* pointer to protocol information entry*/

struct sockaddr_in sin;/* an Internet endpoint address*/

int s, type;/* socket descriptor and socket type*/

memset(&sin, 0, sizeof(sin));

sin.sin_family = AF_INET;

sin.sin_addr.s_addr = INADDR_ANY;

/* Map service name to port number */

if ( pse = getservbyname(service, transport) )

sin.sin_port = htons(ntohs((unsigned short)pse->s_port)+ portbase);

else

if ((sin.sin_port=htons((unsigned short)atoi(service)+portbase)) == 0)

errexit("can't create passive service %d \n",sin.sin_port);

/* Map protocol name to protocol number */

if ( (ppe = getprotobyname(transport)) == 0)

errexit("can't get \"%s\" protocol entry\n", transport);

/* Use protocol to choose a socket type */

if (strcmp(transport, "udp") == 0)

type = SOCK_DGRAM;

else

type = SOCK_STREAM;

/* Allocate a socket */

s = socket(PF_INET, type, ppe->p_proto);

if (s < 0)

errexit("can't create socket: %s\n", strerror(errno));

/* Bind the socket */

if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)

errexit("can't bind to %s port: %s\n", service,

strerror(errno));

if (type == SOCK_STREAM && listen(s, qlen) < 0)

errexit("can't listen on %s port: %s\n", service,

strerror(errno));

return s;

}

int passiveTCP(const char *service,int qlen){

return passivesock(service,"tcp",qlen);

}

三、针对TIME服务的UDP客户软件的实现

1.网络拓扑结构:

dbb0270e01d3a9e157947896b3e5506a.png

2.源码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define BUFSIZE 64

#define UNIXEPOCH 2208988800UL

#define MSG "what time is it?\n"

extern int errno;

int errexit(const char *format,...);

int connectsock(const char *host, const char *service, const char *transport );

int connectUDP(const char *host, const char *service);

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

char *host= "localhost";

char *service= "time";

time_t now;

int s,n;

switch(argc){

case 1:

host = "localhost";

break;

case 3:

service = argv[2];

case 2:

host=argv[1];

break;

default:

fprintf(stderr,"usage: UDPtime[host[port]]\n");

exit(1);

}

s=connectUDP(host,service);

(void)write(s,MSG,strlen(MSG));

n=read(s,(char *)&now,sizeof(now));

if(n<0)    errexit("read failed: %s\n",strerror(errno));

now=ntohl((unsigned long)now);

now-=UNIXEPOCH;

printf("%s",ctime(&now));

exit(0);

}

int errexit(const char *format,...){

va_list arg;

va_start(arg, format);

vfprintf(stderr,format,arg);

va_end(arg);

exit(1);

}

int connectsock(const char *host, const char *service, const char *transport )

/*

* Arguments:

*      host      - name of host to which connection is desired

*      service  - service associated with the desired port

*      transport - name of transport protocol to use ("tcp" or "udp")

*/

{

struct hostent  *phe;  /* pointer to host information entry    */

struct servent  *pse;  /* pointer to service information entry */

struct protoent *ppe;  /* pointer to protocol information entry*/

struct sockaddr_in sin; /* an Internet endpoint address    */

int s, type;    /* socket descriptor and socket type    */

memset(&sin, 0, sizeof(sin));

sin.sin_family = AF_INET;

/* Map service name to port number */

if ( pse = getservbyname(service, transport) )

sin.sin_port = pse->s_port;

else if ((sin.sin_port=htons((unsigned short)atoi(service))) == 0)

errexit("can't get \"%s\" service entry\n", service);

/* Map host name to IP address, allowing for dotted decimal */

if ( phe = gethostbyname(host) )

memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);

else if ( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE )

errexit("can't get \"%s\" host entry\n", host);

/* Map transport protocol name to protocol number */

if ( (ppe = getprotobyname(transport)) == 0)

errexit("can't get \"%s\" protocol entry\n", transport);

/* Use protocol to choose a socket type */

if (strcmp(transport, "udp") == 0)

type = SOCK_DGRAM;

else

type = SOCK_STREAM;

/* Allocate a socket */

s = socket(PF_INET, type, ppe->p_proto);

if (s < 0)

errexit("can't create socket: %s\n", strerror(errno));

/* Connect the socket */

if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)

errexit("can't connect to %s.%s: %s\n", host, service,

strerror(errno));

return s;

}

int connectUDP(const char *host, const char *service){

return connectsock(host,service,"udp");

}

四、针对TIME服务的UDP服务器端软件的实现

1.网络拓扑结构:

037d53808db93fa354cc368a9270e0c5.png

2.源码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define UNIXEPOCH 2208988800UL

extern int errno;

unsigned short portbase = 0;

int errexit(const char *format,...);

int passivesock(const char *service, const char *transport, int qlen);

int passiveUDP(const char *service);

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

char *service= "time";

struct sockaddr_in fsin;

char buf[1];

int sock;

time_t now;

unsigned int alen;

switch(argc){

case 1:

break;

case 2:

service=argv[1];

break;

default:

errexit("usage: UDPtimed [port]\n");

}

sock=passiveUDP(service);

while(1){

alen=sizeof(fsin);

if(recvfrom(sock,buf,sizeof(buf),0,(struct sockaddr *)&fsin,&alen)<0)

errexit("recvfrom: %s\n",strerror(errno));

(void)time(&now);

now=htonl((unsigned long)(now+UNIXEPOCH));

(void)sendto(sock,(char*)&now,sizeof(now),0,(struct sockaddr *)&fsin,sizeof(fsin));

}

}

int errexit(const char *format,...){

va_list arg;

va_start(arg, format);

vfprintf(stderr,format,arg);

va_end(arg);

exit(1);

}

int passivesock(const char *service, const char *transport, int qlen)

/*

* Arguments:

*      service  - service associated with the desired port

*      transport - transport protocol to use ("tcp" or "udp")

*      qlen      - maximum server request queue length

*/

{

struct servent*pse;/* pointer to service information entry*/

struct protoent *ppe;/* pointer to protocol information entry*/

struct sockaddr_in sin;/* an Internet endpoint address*/

int s, type;/* socket descriptor and socket type*/

memset(&sin, 0, sizeof(sin));

sin.sin_family = AF_INET;

sin.sin_addr.s_addr = INADDR_ANY;

/* Map service name to port number */

if ( pse = getservbyname(service, transport) )

sin.sin_port = htons(ntohs((unsigned short)pse->s_port)+ portbase);

else

if ((sin.sin_port=htons((unsigned short)atoi(service)+portbase)) == 0)

errexit("can't create passive service %d \n",sin.sin_port);

/* Map protocol name to protocol number */

if ( (ppe = getprotobyname(transport)) == 0)

errexit("can't get \"%s\" protocol entry\n", transport);

/* Use protocol to choose a socket type */

if (strcmp(transport, "udp") == 0)

type = SOCK_DGRAM;

else

type = SOCK_STREAM;

/* Allocate a socket */

s = socket(PF_INET, type, ppe->p_proto);

if (s < 0)

errexit("can't create socket: %s\n", strerror(errno));

/* Bind the socket */

if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)

errexit("can't bind to %s port: %s\n", service,

strerror(errno));

if (type == SOCK_STREAM && listen(s, qlen) < 0)

errexit("can't listen on %s port: %s\n", service,

strerror(errno));

return s;

}

int passiveUDP(const char *service){

return passivesock(service,"udp",0);

}

这里是用的我实验时的代码,前两个是关于echo服务的客户端与服务器端,有下面运行截图:

ad6f95d4739a02ddcf6b85daef9c17ee.png

后两个是关于time服务的,有下面运行截图:

5d1989ef922a2641acb75fd23175a52c.png

实验时由于多次运行验证,总会出现端口占用的情况,于是这里每次运行时都输入程序的入口参数(就是main函数里的形参),自选端口,方便至极。还有就是代码里多个函数可以写入多个cpp里,这里偷懒了。

0b1331709591d260c1c78e86d0c51c18.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值