东北大学计算机网络实验报告.docx
《东北大学计算机网络实验报告.docx》由会员分享,可在线阅读,更多相关《东北大学计算机网络实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
东北大学计算机网络实验报告
计算机网络实验报告
实验名称
Tcp与Udp的通信实现
班级
软信1101
学号
20112329
姓名
杜海涛
日期
2013-7-13
成绩
评阅人
软件学院
一、实验目的与意义
1、编写Tcp服务器与客户端程序,服务器程序在客户端连接后输出客户端信息(IP,端口号)
2、编写Tcp服务器与客户端程序,客户端在连接后可从键盘输入字符,在服务器端实时显
3、在2的基础上,服务器判断接收到的字符,如是某指定字符,则服务器退出监听
4、编写基于Udp的控制台聊天程序
通过tcp和udp的编程实现windows环境下的进程间的通信。
二、实验环境
操作系统:
Windows7
实验环境:
MicrosoftVisualC++6.0
三、实验的预习内容
传输控制协议TCP(TransportControlProtocol)是一种面向连接的,可靠的传输层协议。
面向连接是指一次正常的TCP传输需要通过在TCP客户端和TCP服务端建立
特定的虚电路连接来完成,该过程通常被称为“三次握手”。
举例说明,TCP客户端需要和TCP服务端建立连接,过程如图所示
第一步中,客户端向服务端提出连接请求。
这时TCPSYN标志置位。
客户端告诉服务端序列号区域合法,需要检查。
客户端在TCP报头的序列号区中插入自己的ISN。
服务端收到该TCP分段后,在第二步以自己的ISN回应(SYN标志置位),同时确认收到客户端的第一个TCP分段(ACK标志置位)。
在第三步中,客户端确认收到服务端的ISN(ACK标志置位)。
到此为止建立完整的TCP连接,开始全双工模式的数据传输过程。
UDP(UserDatagramProtocol),即用户数据报协议。
它属于“面向无连接的
不可靠的传输”的类型。
UDP中,每个数据包称为“数据报”,它的包头只包含4个域,主要是地址信息与包的长度和校验信息。
与此对应,TCP包的头信息有10多个域。
因此UDP的网络开销一般要小于TCP。
由于UDP在传送数据过程中没有建立连接,也不进行检查,因此UDP是不可靠的,它不能保证数据报能安全无误地到达目的主机。
四、实验的步骤与调试方法
程序的流程图
UDP协议下实验:
程序流程图:
五、实验数据与实验结果
Tcpclient
Tcperver
Udpclient
Udpserver
六、实验用程序清单(要有注释)
TCPSERVER:
//ModuleName:
tcpserver.cpp
#include
#include
#pragmacomment(lib,"ws2_32.lib")
voidmain(void)
{
WSADATAwsaData;
SOCKETListeningSocket;
SOCKETNewConnection;
SOCKADDR_INServerAddr;
SOCKADDR_INClientAddr;
intClientAddrLen;
intPort=5150;
intRet;
charDataBuffer[1024];
//InitializeWinsockversion2.2
if((Ret=WSAStartup(MAKEWORD(2,2),&wsaData))!
=0)
{
printf("WSAStartupfailedwitherror%d\n",Ret);
return;
}
//Createanewsockettolisteningforclientconnections.
if((ListeningSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))
==INVALID_SOCKET)
{
printf("socketfailedwitherror%d\n",WSAGetLastError());
WSACleanup();
return;
}
ServerAddr.sin_family=AF_INET;
ServerAddr.sin_port=htons(Port);
ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY);
//Associatetheaddressinformationwiththesocketusingbind.
if(bind(ListeningSocket,(SOCKADDR*)&ServerAddr,sizeof(ServerAddr))
==SOCKET_ERROR)
{
printf("bindfailedwitherror%d\n",WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return;
}
//Listenforclientconnections.Weusedabacklogof5whichis
//normalformanyapplications.
if(listen(ListeningSocket,5)==SOCKET_ERROR)
{
printf("listenfailedwitherror%d\n",WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return;
}
printf("等待客户端连接端口%d.\n",Port);
//Acceptanewconnectionwhenonearrives.
ClientAddrLen=sizeof(ClientAddr);
if((NewConnection=accept(ListeningSocket,(SOCKADDR*)&ClientAddr,
&ClientAddrLen))==INVALID_SOCKET)
{
printf("acceptfailedwitherror%d\n",WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return;
}
printf("成功建立连接%s\n",
inet_ntoa(ClientAddr.sin_addr));
closesocket(ListeningSocket);
//StartsendingandreceivingdataonNewConnection.Forsimplicity,
//wewilljustreceivesomedataandreporthowmanybyteswere
//received.
printf("等待接收数据...\n");\
printf("IPis%s\n",inet_ntoa(ClientAddr.sin_addr));//打印ip地址
printf("portis%d\n",htons(ClientAddr.sin_port));//打印端口号
While(flag)
{
if((Ret=recv(NewConnection,DataBuffer,sizeof(DataBuffer),0))//接收数据
==SOCKET_ERROR)
{
printf("recvfailedwitherror%d\n",WSAGetLastError());
closesocket(NewConnection);
WSACleanup();
return;
}
if(i=strcmp(buffer,"back")==0)//如果是指定字符断开连接
{
flag=0;
}
if(flag)
{
*(DataBuffer+Ret)='\0';
printf("成功接收数据%s,共%dbyte(s).\n",DataBuffer,Ret);
}
}
printf("准备关闭客户端连接.\n");
closesocket(NewConnection);
//Whenyourapplicationisfinishedhandlingtheconnections
//callWSACleanup.
WSACleanup();
}
//tcpclient.exe
//
TCPCLIENT:
#include
#include
voidmain(void)
{
WSADATAwsaData;
SOCKETs;
SOCKADDR_INServerAddr;
intPort=5150;
intRet;
Charsendbuf[100];
//InitializeWinsockversion2.2
if((Ret=WSAStartup(MAKEWORD(2,2),&wsaData))!
=0)
{
printf("WSAStartupfailedwitherror%d\n",Ret);
return;
}
//Createanewsockettomakeaclientconnection.
if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))
==INVALID_SOCKET)
{
printf("socketfailedwitherror%d\n",WSAGetLastError());
WSACleanup();
return;
}
ServerAddr.sin_family=AF_INET;
ServerAddr.sin_port=htons(Port);
ServerAddr.sin_addr.s_addr=inet_addr("127.0.0.1");//本机ip
//Makeaconnectiontotheserverwithsockets.
printf("readytoconnect%s:
%d...\n",inet_ntoa(ServerAddr.sin_addr),htons(ServerAddr.sin_port));
if(connect(s,(SOCKADDR*)&ServerAddr,sizeof(ServerAddr))
==SOCKET_ERROR)
{
printf("connectfailedwitherror%d\n",WSAGetLastError());
closesocket(s);
WSACleanup();
return;
}
printf("客户端连接成功.\n");
//Atthispointyoucanstartsendingorreceivingdataon
//thesockets.Wewilljustsendahellomessagetotheserver.
printf("准备传送数据\n");
while
(1)
{
printf("inputyourword:
>");
fflush(stdin);
scanf("%s",sendbuf);
printf("\n");
if(strcmp(sendbuf,"back")==0)//如果是指定字符退出连接
{
break;
send(s,sendbuf,sizeof(sendbuf),0)
}
if((Ret=send(s,sendbuf,sizeof(sendbuf),0))==SOCKET_ERROR)
{
printf("sendfailedwitherror%d\n",WSAGetLastError());
closesocket(s);
WSACleanup();
return;
}
printf("成功发送数据%dbyte(s).\n",Ret);
}
//Whenyouarefinishedsendingandreceivingdataonsockets,
//youshouldclosethesocket.
printf("关闭连接.\n");
closesocket(s);
//Whenyourapplicationisfinishedhandlingtheconnection,call
//WSACleanup.
WSACleanup();
}
UDPSERVER:
#include
#include
voidmain()
{
WORDwVersionRequested;
WSADATAwsaData;
interr;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!
=0)
{
return;
}
if(LOBYTE(wsaData.wVersion)!
=1||
HIBYTE(wsaData.wVersion)!
=1)
{
WSACleanup();
return;
}
SOCKETsockSrv=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_INaddrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
charrecvBuf[100];
charsendBuf[100];
chartempBuf[200];
SOCKADDR_INaddrClient;
intlen=sizeof(SOCKADDR);
while
(1)
{
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
if('q'==recvBuf[0])
{
sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len);
printf("chatend!
\n");
break;
}
sprintf(tempBuf,"%ssay:
%s",inet_ntoa(addrClient.sin_addr),recvBuf);
printf("%s\n",tempBuf);
printf("Pleaseinputdata:
\n");
gets(sendBuf);
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);
}
closesocket(sockSrv);
WSACleanup();
}
UDPCLIENT:
#include
#include
voidmain()
{
WORDwVersionRequested;
WSADATAwsaData;
interr;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!
=0)
{
return;
}
if(LOBYTE(wsaData.wVersion)!
=1||
HIBYTE(wsaData.wVersion)!
=1)
{
WSACleanup();
return;
}
SOCKETsockClient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_INaddrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
charrecvBuf[100];
charsendBuf[100];
chartempBuf[200];
intlen=sizeof(SOCKADDR);
while
(1)
{
printf("Pleaseinputdata:
\n");
gets(sendBuf);
sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrSrv,len);
recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);
if('q'==recvBuf[0])
{
sendto(sockClient,"q",strlen("q")+1,0,(SOCKADDR*)&addrSrv,len);
printf("chatend!
\n");
break;
}
sprintf(tempBuf,"%ssay:
%s",inet_ntoa(addrSrv.sin_addr),recvBuf);
printf("%s\n",tempBuf);
}
closesocket(sockClient);
WSACleanup();
}
七、结束语
通过本次实验,基本掌握了基于C语言的socket编程。
同时,我也进一步了解了TCP、UDP两种协议的不同。
通过上网查阅资料以及和同学讨论,编程实现基于TCP协议或UDP协议的简单的客户机/服务器程序。
此次实验不仅让我重温了已学过的知识,也使我学到了一些新的知识。
实验成绩
考查内容
分数
得分
做好实验内容的预习,写出预习报告
10
了解实验题目的调试方法
10
按实验要求预先设计好程序
10
认真记录实验数据并分析实验结果
10
实验后按要求书写实验报告,记录实验用数据及运行结果
30
创新能力强,在实验中设计的程序有一定的通用性,算法优化
20
实验过程中,具有严谨的学习态度,认真、踏实、一丝不苟的科学作风
10