tcpip实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《TCP/IP》实验报告
姓名:
学号:
学院:
专业:
班级:
指导老师:
2013年6月3日
实验一熟悉Linux编程环境
练习1:编写一个并发程序,利用fork函数创建五个进程,让每一个进程打印出可用来分辨不同进程的信息。
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
int main()
{
int pid, i;
i = 0;
while(i < 5)
{
i++;
if((pid=fork()) == 0)
{
printf("pid:%d\n",getpid());
sleep(3);
break;
}
waitpid(pid,(int*)0,0);
printf("ppid:%d\n",getpid());
}
return 0;
}
运行结果:
练习2:编写一个程序,利用execve函数改变进程执行的代码。
//execve.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc,char *argv[])
{
char *newargv[] = {NULL,"you","me",NULL};
char *newenviron[]={NULL};
if(argc != 2)
{
fprintf(stderr,"Usage:%s <file-to-exec>\n",argv[0]);
exit(EXIT_FAILURE);
}
newargv[0] = argv[1];
execve(argv[1],newargv,newenviron);
perror("execve");
exit(EXIT_FAILURE);
}
//myecho.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc, char *argv[])
{
int i;
for(i = 0; i < argc; i++)
printf("argv[%d]:%s\n",i,argv[i]);
return 0;
}
运行结果:
实验二实现Echo服务客户端程序(UDP)
代码:
//client.c
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/time.h>
#include<errno.h>
int readable_timeo(int fd, int sec)
{
fd_set rset;
struct timeval tv;
FD_ZERO(&rset);
FD_SET(fd,&rset);
_sec = sec;
_usec = 0;
return (select(fd+1,&rset,NULL,NULL,&tv)); //使用select函数实现简单超时重传}
int main(int argc, char **argv)
{
int sockfd, len, res, i;
struct sockaddr_in address;
char *host;
struct hostent *hostinfo;
struct servent *servinfo;
char buf[128], buf2[128];
int nsec = 20;//timeout:20s
struct timeval tpstart,tpend;
double timeuse;
if(argc == 1)
host = "localhost";
else
host = argv[1];
hostinfo = gethostbyname(host);
if(!hostinfo)
{
fprintf(stderr,"no host:%s\n",host);
exit(1);
}
servinfo = getservbyname("echo","udp");
if(!servinfo)
{
fprintf(stderr,"no echo server!\n");
exit(1);
}
sockfd = socket(AF_INET,SOCK_DGRAM,0);
address.sin_family = AF_INET;
address.sin_port = servinfo->s_port;
address.sin_addr = *(struct in_addr*)*hostinfo->h_addr_list;
len = sizeof(address);
while(fgets(buf,128,stdin) != NULL)
{
for(i = 0; i < 2; i++) //juse one chance to resend
{
if(i == 1) //resend
{
printf("ReSend!!!\n");
gettimeofday(&tpend,NULL);
timeuse=1000000*(__sec)+__usec;
timeuse/=1000000;
printf("resend time is %lf s\n",timeuse);
}
gettimeofday(&tpstart,NULL);
res = sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&address,len);
if(readable_timeo(sockfd,nsec) == 0)
{
fprintf(stderr,"socket timeout\n");
continue;
}
res = recvfrom(sockfd,buf2,128,0,(struct sockaddr*)&address,&len);
buf2[res] = 0;
fputs(buf2,stdout);
break; //send successfully,quit!
}
}
close(sockfd);
exit(0);
}
实验三循环无连接服务器Echo的实现代码:
//server.c
#include<stdio.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<stdlib.h>
#include<signal.h>
#include<string.h>
#include<errno.h>
#include<time.h>
#define MAXLINE 128
int sockfd, flag = 1;
void close_action(int sig)
{
printf("close the sockfd\n");
close(sockfd);
signal(SIGINT,SIG_DFL);
flag = 0;
}
int main()
{
struct sockaddr_in sin,sin_cli;
int type, res, opt;
char mesg[MAXLINE], buf[MAXLINE];
socklen_t len;
struct sigaction act;
struct tm *ptm;
int y,m,d,h,n,s;
long ts;
//set the signal action
act.sa_handler = close_action;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
memset(&sin,0,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(45454);
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd < 0)
{
fprintf(stderr,"can't create socket %s \n",strerror(errno));
exit(1);
}
if(bind(sockfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
{
fprintf(stderr,"can't bind to %s port:%s\n",service,strerror(errno));
exit(1);
}
len = sizeof(sin_cli);
sigaction(SIGINT,&act,0); //Ctrl+C close the sockfd
while(flag)
{
printf("\n");
res = recvfrom(sockfd,mesg,MAXLINE,0,(struct sockaddr*)&sin_cli,&len);
mesg[res] = 0;
ts = time(NULL);
sprintf(buf,"%.24s\r\n",ctime(&ts));
printf("%s\t",buf);
printf("%s\t",inet_ntoa(sin_cli.sin_addr));
sendto(sockfd,mesg,n,0,(struct sockaddr*)&sin_cli,len);
}
exit(0);
}
实验四循环的、面向连接服务器的实现
//server.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<time.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#define MAXSIZE 30
int main()
{
struct sockaddr_in servaddr,cliaddr;
int clilen;
int connfd, listenfd;
char buf[MAXSIZE];
time_t now;
int seconds;
struct tm *ptm;
int y,m,d,h,n,s;
long ts;
listenfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9734);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
listen(listenfd,5);
for(;;)
{
clilen = sizeof(cliaddr);
connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen);
ts = time(NULL);
sprintf(buf,"%.24s\r\n",ctime(&ts));
write(connfd,buf,MAXSIZE);
}
exit(1);
}
//client.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<time.h>
#include<string.h>
#define MAXSIZE 30
void str_daytime(int fd)
{
char buf[MAXSIZE];
int n;
if((n = read(fd,buf,MAXSIZE)) <= 0)
{
fprintf(stderr,"error");
}
buf[n] = 0;
fputs(buf,stdout);
}
int main(int argc,char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
sockfd = socket(AF_INET,SOCK_STREAM,0);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9734);
//Inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
str_daytime(sockfd);
exit(1);
}
实验五循环的、面向连接服务器的实现
//server.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<time.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#define MAXSIZE 30
int main()
{
struct sockaddr_in servaddr,cliaddr;
int clilen,connfd, listenfd, childpid
char buf[MAXSIZE];
time_t now;
int seconds;
struct tm *ptm;
int y,m,d,h,n,s;
long ts;
listenfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9734);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
listen(listenfd,5);
clilen = sizeof(cliaddr);
for(;;)
{
connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen);
if((childpid = fork()) == 0)
{
close(listenfd);
ts = time(NULL);
sprintf(buf,"%.24s\r\n",ctime(&ts));
write(connfd,buf,MAXSIZE);
}
close(connfd);
}
exit(1);
}
//test.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
int i;
for(i = 0; i < 10; i++)
{
system("./tcpcli");
printf("\n");
}
exit(0);
}
实验六单进程并发服务
代码:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/select.h>
#include<strings.h>
#include<string.h>
#include<time.h>
#define MAXLINE 128
int main()
{
struct sockaddr_in servaddr,cliaddr;
int clilen;
int connfd, listenfd, sockfd;
char buf[MAXLINE];
int i, maxi, maxfd, seconds, nresult, res, nread,client[FD_SETSIZE];
pid_t childpid;
fd_set readfds,testfds;
struct tm *ptm;
int y,m,d,h,n,s;
time_t ts;
listenfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9734);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
listen(listenfd,10);
maxfd = listenfd;
maxi = -1;
for(i = 0; i < FD_SETSIZE; i++)
client[i] = -1;
FD_ZERO(&readfds);
FD_SET(listenfd,&readfds);
for(;;)
{
testfds = readfds;
nresult = select(maxfd+1,&testfds,NULL,NULL,NULL);
if(FD_ISSET(listenfd,&testfds))
{
clilen = sizeof(cliaddr);
connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen);
for(i = 0; i < FD_SETSIZE; i++)
if(client[i] < 0)
{
client[i] = connfd;
break;
}
if(i == FD_SETSIZE)
fprintf(stderr,"too many clients");
FD_SET(connfd,&readfds);
if(connfd > maxfd)
maxfd = connfd;
if(i > maxi)
maxi = i;
if(--nresult <= 0)
continue;
}
for(i = 0; i <= maxi; i++)
{
if((sockfd = client[i]) < 0)
continue;
if(FD_ISSET(sockfd,&testfds))
{
if((res = read(sockfd,buf,MAXLINE))== 0)
{
close(sockfd);
printf("connection closed by client\n");
FD_CLR(sockfd,&readfds);
client[i] = -1;
}
else if(res > 0)
{
printf("supply service to client!\n");
ts = time(NULL);
sprintf(buf,"%.24s",ctime(&ts));
write(sockfd,buf,strlen(buf));
}
else
printf("error!!!!\n");
if(--nresult <= 0)
{
printf("no more readble descriptors\n");
break;
}
}
}
}
exit(1);
}
实验七并发的客户端
//tcpcli.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include "unp.h"
int main(int argc,char **argv)
{
int i, ccount, hcount = 0, fd, maxfd = 0, n, one, sockfd;
fd_set afds;
char ser_ip[FD_SETSIZE][20], buf[MAXLINE];
struct sockaddr_in servaddr;
struct servent *servinfo;
servinfo = getservbyname("daytime","tcp");
servaddr.sin_family = AF_INET;
servaddr.sin_port = servinfo->s_port;
for(i = 1; i < argc; ++i)
{
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(strcmp(argv[i],"-c") == 0)
{
if(++i < argc && (ccount = atoi(argv[i])))
continue;
err_quit("tcpcli [-c] [number] [ip] ");
}
Inet_pton(AF_INET,argv[i],&servaddr.sin_addr);
fd = connect(sockfd,(SA*)&servaddr,sizeof(servaddr));
if(ioctl(sockfd,FIONBIO,(char*)&one))
err_quit("can't mark socket nonblocking:%s\n",strerror(errno));
if(sockfd > maxfd)
maxfd = sockfd;
strcpy(ser_ip[sockfd],argv[i]);
++hcount;
FD_SET(sockfd,&afds);
}
n = select(maxfd+1,&afds,NULL,NULL,NULL);
for(i = 0; i <= maxfd; i++)
{
if(FD_ISSET(i,&afds))
{
if((n = read(i,buf,MAXLINE)) == 0)
{
close(sockfd);
FD_CLR(i,&afds);
}
else
printf("%s\t%s\n",buf,ser_ip[i]);
}
}
exit(0);
}
实验八多线程服务
代码:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<time.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<semaphore.h>
#include<pthread.h>
#define MAXSIZE 30
struct share_thread
{
pthread_mutex_t work_mutex;
int count;
}shared;
void *thread_func(void *arg)
{
int connfd;
char buf[MAXSIZE];
struct tm *ptm;
int y,m,d,h,n,s;
long ts;
connfd = *(int*)arg;
ts = time(NULL);
sprintf(buf,"%.24s\r\n",ctime(&ts));
write(connfd,buf,MAXSIZE);
pthread_mutex_lock(&shared.work_mutex);
shared.count++;
pthread_mutex_unlock(&shared.work_mutex);
printf("Number of service of daytime:%d\n",shared.count);
close(connfd);
pthread_exit(0);
}
int main()
{
struct sockaddr_in servaddr, cliaddr;
int listenfd, connfd;
pthread_t serv_thread;
pthread_attr_t thread_attr;
int res;
int clilen;
shared.count = 0;
res = pthread_mutex_init(&shared.work_mutex,NULL);
if(res != 0)
{
fprintf(stderr,"mutex initilization failed");
exit(1);
}
res = pthread_attr_init(&thread_attr);
if(res != 0)
{
fprintf(stderr,"Attribute creation failed");
exit(1);
}
res = pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED);
if(res != 0)
{
fprintf(stderr,"Setting detached attribute failed");
exit(1);
}
listenfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9734);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
listen(listenfd,5);
for(;;)
{
clilen = sizeof(cliaddr);
connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen);
//wrong
res = pthread_create(&serv_thread,&thread_attr,thread_func,(void*)&connfd);
if(res != 0)
{
fprintf(stderr,"create pthread failed\n");
exit(1);
}
}
exit(1);
}
实验九预分配进程服务器
代码://server.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<time.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<signal.h>
#include<errno.h>
#include<sys/wait.h>
#include<pthread.h>
#include<semaphore.h>
#define MAXSIZE 30
#define MAXCHILD 100
static pthread_mutex_t work_mutex;
static pid_t childpid[MAXCHILD];
void child_main(int i, int listenfd)
{
char buf[MAXSIZE];
struct tm *ptm;
int y,m,d,h,n,s;
long ts;
int connfd;
int clilen;
struct sockaddr_in cliaddr;
clilen = sizeof(cliaddr);
pthread_mutex_lock(&work_mutex); //lock
connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen);
pthread_mutex_unlock(&work_mutex); //unlock
printf("Now, it is the %d child to supply service for the client\n",i);
ts = time(NULL);
sprintf(buf,"%.24s\r\n",ctime(&ts));
write(connfd,buf,MAXSIZE);
close(connfd);
}
void sig_int(int signo)
{
printf("\ndestroy the mutex\n");
int i;
for(i = 0; i < MAXCHILD; i++)
kill(childpid[i],SIGTERM);
while(wait(NULL) > 0);
if(errno != ECHILD)
fprintf(stderr,"wait error");
pthread_mutex_destroy(&work_mutex);
exit(0);
}
int main()
{
struct sockaddr_in servaddr, cliaddr;
int listenfd, connfd;
int res, i;
int clilen;
res = pthread_mutex_init(&work_mutex,NULL);
if(res != 0)
{
fprintf(stderr,"mutex initialization failed\n");
exit(1);
}
listenfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9734);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
listen(listenfd,5);
for(i = 0; i < MAXCHILD; i++)
{
if((childpid[i] = fork()) < 0)
{
fprintf(stderr,"fork failed");
exit(1);
}
else if(childpid[i] == 0)
child_main(i, listenfd);
}
signal(SIGINT,sig_int);
for(;;)
pause();
}。