您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 实验五--关于tcp套接字编程
实验五关于tcp套接字编程一、实验目的1熟悉基本TCP套接字编程流程(服务器端、客户端)2掌握流程中的关键函数的用法二、实验要求1将实例程序录入、编译、运行,写出运行结果2写出套接字定义相关的语句(服务器端、客户端分开写)3写出能体现TCP套接字编程流程的语句(服务器端、客户端分开写)4写出除上诉相关语句及头文件之外的语句注释三、实例程序服务器端客户端运行:运行服务器端程序./服务器端程序名称运行客户端程序./客户端程序名称+空格+127.0.0.1服务器端1.#includestdio.h2.#includestring.h3.#includeunistd.h4.#includesys/types.h5.#includesys/socket.h6.#includenetinet/in.h7.#includearpa/inet.h8.#includestdlib.h//1~8行:所需要的头文件9.#definePORT1234//定义端口号为1234;10.#defineBACKLOG1//最大允许连接的数量BACKLOG定义为111.main()12.{13.intlistenfd,connectfd;14.structsockaddr_inserver;15.structsockaddr_inclient;16.socklen_taddrlen;17.if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)18.{19.perror(socket()error.);20.exit(1);21.}//17~21行:调用socket()函数,产生TCP套接字。如果出错,打印错误信息。22.intopt=SO_REUSEADDR;23.setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));//22~23行:设置套接字选项SO_REUSEADDR,即地址重用选项。由于系统默认是只允许一个套接字绑定在一个特定的协议地址上,并且当该套接字关闭后,系统仍不允许在该地址上绑定其它套接字。如果去掉这两行,程序运行时产生的错误信息为:Bind()error;Addressalreadyinuse.24.bzero(&server,sizeof(server));25.server.sin_family=AF_INET;26.server.sin_port=htons(PORT);27.server.sin_addr.s_addr=htonl(INADDR_ANY);//24`27行:初始化server套接字地址结构,并对地址结构中的成员赋值。当前的本地地址设为INADDR_ANY,接收目的地址是本机IP的客户端连接,这里的端口号和IP地址都要转换成网络字节序。28.if(bind(listenfd,(structsockaddr*)&server,sizeof(server))==-1)29.{30.perror(Bind()error);31.exit(1);32.}//28~32行:将套接字和指定的协议地址绑定.33.if(listen(listenfd,BACKLOG)==-1)34.{35.perror(listen()error\n);36.exit(1);37.}//33~37行:将套接字描述符转换成监听描述符,等待客户的连接.38.addrlen=sizeof(client);39.if((connectfd=accept(listenfd,(structsockaddr*)&client,&addrlen))==-1)40.{41.perror(accept()error\n);42.exit(1);43.}//39~43行:接受客户连接,客户的地址信息存放在client地址结构中.44.printf(yougotaconnectionfromcient'sipis%s,portis%d\n,inet_ntoa(client.sin_addr),htons(client.sin_port));//显示客户的IP地址和端口号通过inet_ntoa()函数将IP地址转换成可显示的ASCII字符串,通过htons()函数将端口号转换成网络字节序。45.send(connectfd,welcome\n,8,0);//发送Welcome字符串给客户端46.close(connectfd);47.close(listenfd);//46~47行:关闭套接字。线关闭已连接套接字,再关闭监听套接字48.}客户端1.#includestdio.h2.#includeunistd.h3.#includestrings.h4.#includesys/types.h5.#includesys/socket.h6.#includenetinet/in.h7.#includenetdb.h8.#includestdlib.h//1~8行:所需的头文件9.#definePORT1234//定义端口号为1234;10.#defineMAXDATASIZE100//接收缓冲器大小为10011.intmain(intargc,char*argv[])12.{13.intsockfd,num;14.charbuf[MAXDATASIZE];15.structhostent*he;16.structsockaddr_inserver;17.if(argc!=2)18.{19.printf(usage:%sIPaddress\n,argv[0]);20.exit(1);21.}//17~21行:检查用户的输入。如果用户输入不正确,提示用户正确的输入方式22.if((he=gethostbyname(argv[1]))==NULL)23.{24.printf(gethostbyname()error\n);25.exit(1);26.}//22~26行:通过用户输入的点分十进制形式的IP地址,获得服务器的相关地址信息27.if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)28.{29.printf(socket()error\n);30.exit(1);31.}//27~31行:调用socket()函数产生套接字描述符32.bzero(&server,sizeof(server));33.server.sin_family=AF_INET;34.server.sin_port=htons(PORT);35.server.sin_addr=*((structin_addr*)he-h_addr);//32~35行:初始化服务器的地址结构,并为地址结构的成员赋值36.if(connect(sockfd,(structsockaddr*)&server,sizeof(server))==-1)37.{38.printf(connect()error\n);39.exit(1);40.}//36~40行:调用connect()函数连接到服务器server41.if((num=recv(sockfd,buf,MAXDATASIZE,0))==-1)42.{43.buf[num-1]='\0';44.exit(1);45.}//41~45行:接收服务器发过来的字符串,保存在buf中。接收的真正字节数被存储在num中。46.buf[num-1]='\0';//以\0标志字符串的结束47.printf(servermessage:%s\n,buf);//显示从服务器接收到的buf信息48.close(sockfd);//关闭套接字49.}套接字定义相关的语句服务器端:structsockaddr_inserver;//定义server的套接字地址结构structsockaddr_inclinet;//定义clinet的套接字地址结构socklen_taddrlen;//定义通用套接字地址结构bzero(&server,sizeof(server))//初始化serverserver.sin_family=AF_INET;//对地址结构中的成员地址家族赋值server.sin_port=htons(PORT);//对地址结构中的成员端口号赋值server.sin_addr.s_addr=htonl(INADDR_ANY);//当前的本地地址设为INADDR_ANY客户端:structsockaddr_inserver;//定义server的套接字地址结构bzero(&server,sizeof(server))//初始化serverserver.sin_family=AF_INET;//对地址结构中的成员地址家族赋值server.sin_port=htons(PORT);//对地址结构中的成员端口号赋值server.sin_addr=*((structin_addr*)he-h_addr);//对地址结构中的成员IP地址赋值TCP套接字编程流程的语句服务器端:1、socket()函数if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1){perror(socket()error.);exit(1);}//调用socket()函数,产生TCP套接字。如果出错,打印错误信息。2、bind()函数if(bind(listenfd,(structsockaddr*)&server,sizeof(server))==-1){perror(Bind()error);exit(1);}//调用bind()函数将描述符listenfd与server套接字地址结构中的协议地址绑定。3、listen()函数if(listen(listenfd,BACKLOG)==-1){perror(listen()error\n);exit(1);}//调用listen()函数,将listenfd描述符设置为监听描述符4、accept()函数if((connectfd=accept(listenfd,(structsockaddr*)&client,&addrlen))==-1){perror(accept()error\n);exit(1);}//调用accept()函数,接收连接请求,返回已连接套接字描述。与服务器连接的客户端的协议地址可以通过参数client得到,addrlen返回内核写入client结构体中的准确字节数。客户端:1、socket()函数if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){printf(socket()error\n);exit(1);}//调用socket()函数产生套接字描述符2、connect()函数if(connect(sockfd,(structsockaddr*)&server,sizeof(server))==-1){printf(connect()error\n);exit(1);}//调用connect()函数与服务器建立连接。3、recv()函数if((num=recv(sockfd,buf,MAXDATASIZE,0))==-1){buf[num-1]='\0';exit(1);}//接收服务器发过来的字符串,保存在buf中。接收的真正字节数被存储在num中。4、close()函数close(sockfd);//关闭套接字结果如下步骤:首先运行服务器端程序,再运行客户端程序(./客户端程序名称+空格+127.0.0.1)客户端根据用户提供的IP地址172.0.0.1将用户从终端输入的信息发送给服务器,然后等待服务器的回应。服务器:客户端:
本文标题:实验五--关于tcp套接字编程
链接地址:https://www.777doc.com/doc-5406574 .html