西工大计算机网络实验三.docx
- 文档编号:11320393
- 上传时间:2023-02-26
- 格式:DOCX
- 页数:18
- 大小:382.41KB
西工大计算机网络实验三.docx
《西工大计算机网络实验三.docx》由会员分享,可在线阅读,更多相关《西工大计算机网络实验三.docx(18页珍藏版)》请在冰豆网上搜索。
西工大计算机网络实验三
实验报告
实验名称
--SOCKET编程
一、实验目的
(1)加深对TCP和UDP的理解;
(2)实现两台计算机之间TCP/UDP通信。
二、实验过程
原理:
socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。
如下图所示:
TCP通信
原理如图:
代码:
服务器端:
#pragmacomment(lib,"WS2_32.lib")
#include
#include
#include
usingnamespacestd;
intmain()
{
inti=0;
WSADATAwsaData;
SOCKEToldSocket,newSocket;
//客户地址长度
intiLen=0;
//发送的数据长度
intiSend=0;
//接收的数据长度
intircv=0;
//处世要发送给客户的信息
charbuf[20]="Iamaserver";
//接收来自用户的信息
charfromcli[512];
//客户和服务器的SOCKET地址结构
structsockaddr_inser,cli;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!
=0)
{
cout<<"failedtoloadwinsock"< return0; } cout<<"serverwaiting"< cout<<"---------------"< //创建服务器端帧听SOCKET oldSocket=socket(AF_INET,SOCK_STREAM,0); if(oldSocket==INVALID_SOCKET) { cout<<"socket()failed: "< return0; } //以下是建立服务器端的SOCKET地址结构 ser.sin_family=AF_INET; ser.sin_port=htons(5050); //使用系统指定的ip地址INADDR_ANY //ser.sin_addr.s_addr=htonl(INADDR_ANY); ser.sin_addr.s_addr=inet_addr("192.168.8.58"); if(bind(oldSocket,(LPSOCKADDR)&ser,sizeof(ser))==SOCKET_ERROR) { cout<<"bind()failed: "< return0; } //进入侦听状态 if(listen(oldSocket,5)==SOCKET_ERROR) { cout<<"listen()failed: "< return0; } //接收客户端的连接 iLen=sizeof(cli); newSocket=accept(oldSocket,(structsockaddr*)&cli,&iLen);//产生一个新的SOCKET if(newSocket==INVALID_SOCKET) { cout<<"accept()failed: "< return0; } //进入一个无限循环,等待客户发送数据 while (1) { i++; //服务器初始化接收缓冲区 memset(fromcli,0,512); ircv=recv(newSocket,fromcli,sizeof(fromcli),0); if(ircv==SOCKET_ERROR) { cout<<"rcv()failed: "< break; } elseif(ircv==0) break; else{ cout<<"-----服务器接收的内容为--------"< } if(strcmp(fromcli,"quit")==0) break; } closesocket(newSocket); closesocket(oldSocket); WSACleanup(); } 客户端: #pragmacomment(lib,"WS2_32.lib") #include #include #include usingnamespacestd; #defineDATA_BUFFER512 intmain() { WSADATAwsaData; SOCKETsClient; charch; inti=0; char*Serip="192.168.8.58";//随着程序所在主机的地址改变而改变 intSeriPort=5050; //从服务器接收的数据的长度 intiLen; //发送的数据长度 intisnd; //接收缓冲区 charbuf[DATA_BUFFER]; //发送缓冲区 charsndbuf[DATA_BUFFER]; //服务器端SOCKET地址结构 structsockaddr_inser; //接收/发送缓冲区的初始化 memset(buf,0,sizeof(buf)); memset(sndbuf,0,DATA_BUFFER); if(WSAStartup(MAKEWORD(2,2),&wsaData)! =0) { cout<<"failedtoloadwinsock"< return0; } //填写要连接的服务器地址信息 ser.sin_family=AF_INET; ser.sin_port=htons(SeriPort); ser.sin_addr.s_addr=inet_addr(Serip); //建立客户端字节流式套接字 sClient=socket(AF_INET,SOCK_STREAM,0); if(sClient==INVALID_SOCKET) { cout<<"socket()failed: "< return0; } //请求与服务器建立连接 //cout<<"setlink"; if(connect(sClient,(structsockaddr*)&ser,sizeof(ser))==INVALID_SOCKET) { cout<<"connect()failed: "< return0; } else {//向服务器端发送数据 while (1) { cout< i++; cout<<"第"< cin>>sndbuf; isnd=send(sClient,sndbuf,sizeof(sndbuf),0); if(isnd==0) return0; elseif(isnd==SOCKET_ERROR) { cout<<"send()failed: "< return0; } cout<<"-----客户端发送内容为----"< } } closesocket(sClient); WSACleanup(); } 本机上客户端与服务器端通信结果如图: 在两台服务器上分别运行服务器端和客户端,结果如图: UDP通信 原理如图: 代码: 服务器端: #include"stdafx.h" #include #include #include #definebuffer_length512 #pragmacomment(lib,"WS2_32.lib") voidmain() { WSADATAwsadata; SOCKETsSocket; intilen; intirecv; charrecv_buf[buffer_length]; charsend_buf[buffer_length]; //服务器和客户SOCKET地址结构 structsockaddr_inseradd,cliadd; if(WSAStartup(MAKEWORD(2,2),&wsadata)! =0) { printf("failedtoloadwinsocket\n"); return; } sSocket=socket(AF_INET,SOCK_DGRAM,0); if(sSocket==INVALID_SOCKET) { printf("socket()failed: %d\n",WSAGetLastError()); return; } //初始化服务器SOCKET地址结构 seradd.sin_family=AF_INET; seradd.sin_port=htons(6666); //seradd.sin_addr.s_addr=htonl(INADDR_ANY); seradd.sin_addr.s_addr=inet_addr("0.0.0.0"); if(bind(sSocket,(LPSOCKADDR)&seradd,sizeof(seradd))==SOCKET_ERROR) { printf("地址绑定时出错: %d\n",WSAGetLastError()); intrua; scanf("%d",&rua); return; } ilen=sizeof(cliadd); //初始化接收缓冲区 memset(recv_buf,0,sizeof(recv_buf)); irecv=recvfrom(sSocket,recv_buf,buffer_length,0,(structsockaddr*)&cliadd,&ilen); if(irecv==SOCKET_ERROR) { printf("接收出错%d\n",WSAGetLastError()); intrua; scanf("%d",&rua); return; } elseif(irecv==0) return; else { printf("\n%s--",recv_buf); printf("ServerreceivedfromClientip: [%s],port: [%d]\n",inet_ntoa(cliadd.sin_addr),ntohs(cliadd.sin_port)); } while (1) { //在此函数中cli为传出参数 irecv=recvfrom(sSocket,recv_buf,buffer_length,0,(structsockaddr*)&cliadd,&ilen); if(irecv==SOCKET_ERROR) { printf("接收出错%d\n",WSAGetLastError()); intrua; scanf("%d",&rua); return; } elseif(irecv==0) break; else { printf("\n%s--",recv_buf); printf("ServerreceivedfromClientip: [%s],port: [%d]\n",inet_ntoa(cliadd.sin_addr),ntohs(cliadd.sin_port)); } scanf("%s",send_buf); sendto(sSocket,send_buf,sizeof(send_buf),0,(structsockaddr*)&cliadd,sizeof(cliadd)); } closesocket(sSocket); WSACleanup(); } 客户端: #include"stdafx.h" #include #include #definedata_buffer1024 voidmain() { WSADATAwsadata; SOCKETsclient; //服务器地址、端口号 char*serip="192.168.8.58"; intSeriport=6666; charch[]="qita"; //服务器SOCKET地址结构长度 intilen; //发送/接收数据大小 intisend; intirecv; //要发送给服务器的数据 charsend_buf[]="hello,Iamaclient."; charrecv_buf[data_buffer]; //服务器端的SOCKET地址结构 structsockaddr_inseradd,cliadd; //初始化接收缓冲区 memset(recv_buf,0,sizeof(recv_buf)); //字符数组初始化 memset(ch,0,sizeof(ch)); if(WSAStartup(MAKEWORD(2,2),&wsadata)! =0) { printf("failedtoloadwinsock\n"); return; } //服务器SOCKET地址结构初始化 seradd.sin_family=AF_INET; seradd.sin_port=htons(Seriport); seradd.sin_addr.s_addr=inet_addr(serip); cliadd.sin_family=AF_INET; cliadd.sin_port=htons(7777); cliadd.sin_addr.s_addr=inet_addr("0.0.0.0"); sclient=socket(AF_INET,SOCK_DGRAM,0); if(sclient==INVALID_SOCKET) { printf("buildsocketfailed! \n"); return; } if(bind(sclient,(LPSOCKADDR)&cliadd,sizeof(cliadd))==SOCKET_ERROR) { printf("地址绑定时出错: %d\n",WSAGetLastError()); return; } //无连接不需要进行地址与套接字的绑定,直接发送数据即可 ilen=sizeof(seradd); isend=sendto(sclient,send_buf,sizeof(send_buf),0,(structsockaddr*)&seradd,ilen); if(isend! =0&&isend! =SOCKET_ERROR) { //printf("datahasbeensentsuccessfully! \n"); printf("客户所发的数据为: %s,字节数为: %d\n",send_buf,isend); } elsereturn; while (1) { scanf("%s",ch); sendto(sclient,ch,sizeof(ch),0,(structsockaddr*)&seradd,sizeof(seradd)); irecv=recvfrom(sclient,recv_buf,data_buffer,0,(structsockaddr*)&seradd,&ilen); if(irecv==SOCKET_ERROR) { printf("接收出错%d\n",WSAGetLastError()); intrua; scanf("%d",&rua); return; } elseif(irecv==0) break; else { printf("\n%s--",recv_buf); printf("ServerreceivedfromClientip: [%s],port: [%d]\n",inet_ntoa(seradd.sin_addr),ntohs(seradd.sin_port)); } } closesocket(sclient); WSACleanup(); } 本机上客户端与服务器端通信结果如图: 在两台服务器上分别运行服务器端和客户端,结果如图: 三、实验中出现的问题 实验中,因为对TCP和UDP中的代码不熟悉,编译时也缺少了头文件,导致在编译时一直都没有通过,最后在老师的提醒下知道了错误所在,才能编译通过。 思考题: 问: 127.0.0.1与本机配置的网络ip地址还有localhost,相互有什么区别? 答: localhost是个域名,不是地址,它可以被配置为任意的IP地址,不过通常情况下都指向127.0.0.1(ipv4)和[: : 1](ipv6) 整个127.*网段通常被用作loopback网络接口的默认地址,按惯例通常设置为127.0.0.1。 这个地址在其他计算机上不能访问,就算你想访问,访问的也是自己,因为每台带有TCP/IP协议栈的设备基本上都有localhost/127.0.0.1。 本机地址通常指的是绑定在物理或虚拟网络接口上的IP地址,可供其他设备访问到。 四、心得体会 在本次试验之前,我对于socket编程并不了解,通过向同学请教以及从网上查找资料,对于这个问题我有了初步的了解,能够进行简单的应用,实现了本机以及联机的TCP协议以及UDP协议通讯。 这次实验主要是通过改写代码实现两台计算机之间tcp/udp通信,做起来问题不大,但在代码的理解以及使用上有一定的难度,主要都是通过问同学来解决问题。 通过这次实验,明白了计算机是如何进行tcp/udp通信,更加强化了理论知识。 (注: 文档可能无法思考全面,请浏览后下载,供参考。 可复制、编制,期待你的好评与关注)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 西工大 计算机网络 实验