#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)
{
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("cant create passive service %d \n",sin.sin_port);
if ( (ppe = getprotobyname(transport)) == 0)
errexit("cant get \"%s\" protocol entry\n", transport);
if (strcmp(transport, "udp") == 0)
type = SOCK_DGRAM;
else
type = SOCK_STREAM;
s = socket(PF_INET, type, ppe->p_proto);
if (s < 0)
errexit("cant create socket: %s\n", strerror(errno));
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
errexit("cant bind to %s port: %s\n", service,
strerror(errno));
if (type == SOCK_STREAM && listen(s, qlen) < 0)
errexit("cant listen on %s port: %s\n", service,
strerror(errno));
return s;
}
int passiveTCP(const char *service,int qlen){
return passivesock(service,"tcp",qlen);
}
4. 编译并调试程序
切换到源代码所在的目录,使用GCC指令进行编译
$ GCC –o echo_s echo_s.c
八、实验数据及结果分析:
在源程序所在的目录键入./echo_s,同时键入./echo_c命令,得到下面的运行结果:
九、总结、改进建议及心得体会:
1.在实验一中编写了echo服务的客户端程序,本实验中实现了echo服务服务端的程序,实现了客户端和服务端之间通信。
2.本实验中,简要实现了echo服务的整个过程,对echo服务有了比较全面的理解,同时也体会到服务端和客户端在编程实现上存在这较大的差异。
【本文档内容可以自由复制内容或自由编辑修改内容期待你的好评和关注,我们将会做得更好】
精选范本,供参考!