#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include<errno.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/wait.h>
unsigned short portbase=0;
#define QLEN 32
#define LINELEN 4096
int passivesock(const char *service,const char* transport,int qlen)
{
struct servent *pse;
struct protoent *ppe;
struct sockaddr_in sin;
int s,type;
memset(&sin,0,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=INADDR_ANY;
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)))==0)
{perror("cannot get service entry\n");exit(1);}
//errexit("cannot get \"%s\"service entry\n",service);
if((ppe=getprotobyname(transport))==0)
{perror("cannot get protocol entry\n");exit(1);}
//errexit("cannot get \"%s\"protocol entry\n",transport);
if(!strcmp(transport,"udp"))
type=SOCK_DGRAM;
else
type=SOCK_STREAM;
if((s=socket(PF_INET,type,ppe->p_proto))<0)
{perror("cannot create socket\n");exit(1);}
// errexit("cannot create socket:%s\n",strerro(errno));
if(bind(s,(struct sockaddr *)&sin,sizeof(sin))<0)
{perror("cannot bind to port\n");exit(1);}
//errexit("cannot bind to %s port:%s\n",service,strerro(errno));
if(type==SOCK_STREAM&&listen(s,qlen)<0)
{perror("cannot listen on port\n");exit(1);}
// errexit("cannot listen on %s port:%S\n",service,strerror(errno));
return s;
}
int TCPechod(int fd)
{
char buf[LINELEN];
int c;
while(c=read(fd,buf,sizeof(buf))){
if(c<0)
{perror("erro read\n");exit(1);}
if(write(fd,buf,c)<0)
{perror("erro write\n");exit(1);}
}
return 0;
}
reaper(int sig)
{
int status;
while(wait3(&status,WNOHANG,(struct rusage*)0)>=0);
}
int main(int argc, char *argv[])
{
char *service="echo";
char *transport="tcp";
struct sockaddr_in fsin;
unsigned int alen;
int msock,ssock;
int sec;
time_t start,finish;
char *t;
switch(argc)
{
case 1:
break;
case 3:
transport=argv[2];
case 2:
service=argv[1];
break;
default:
{perror("usage:filetransmit[port[tcp/udp]]\n");exit(1);}
}
msock=passivesock(service,transport,QLEN);
signal(SIGCHILD,reaper);
if(!strcmp(transport,"tcp")) //tcp transmit
while(1)
{
alen=sizeof(fsin);
if((ssock=accept(msock,(struct sockaddr*)&fsin,&alen))<0)
{
perror("Accpet error!");
continue;
}
time(&start);
t=(char*)ctime(&start);
printf("start a connection from %s time:%s\n",inet_ntoa(fsin.sin_addr),t);
switch(fork())
{
case 0:
close(msock);
TCPechod(ssock);
time(&finish);
t=(char*)ctime(&finish);
sec=finish-start;
printf("finish the connection from %s time:%s,run time: %d seconds\n",inet_ntoa(fsin.sin_addr),t,sec);
exit(0);
default:
close(ssock);
break;
case -1:
perror("error fork\n");
exit(1);
}
}
else //udp transmit
{
}
return 0;
}
评论0