天津理工大学计算机网络 实验二.docx
《天津理工大学计算机网络 实验二.docx》由会员分享,可在线阅读,更多相关《天津理工大学计算机网络 实验二.docx(9页珍藏版)》请在冰豆网上搜索。
天津理工大学计算机网络实验二
实验报告
学院(系)名称:
计算机与通信工程学院
姓名
学号
专业
计算机科学与技术
班级
实验名称
实验二:
基于TCP/UDP的Socket编程
课程名称
计算机网络
课程代码
实验时间
实验地点
7#219
批改意见
成绩
教师签字:
1.实验目的
了解套接字(socket)实现原理。
通过编成理解TCP、UDP原理,加深对传输层的功能理解。
2.实验环境
Windows7
3.实验要求
请在以下题目中选择一个,按照要求完成实验,并完成实验报告。
实验可以分组进行,每2人一组,在报告中注明每个成员的分工。
编程可以使用任何高级语言,建议使用java或C++。
(1)基于TCP/UDP的socket编程
a)利用Java或C++语言,分别基于TCP和UDP编写一个简单的Client/Server网络应用程序。
要求实现客户向服务器传输任意一个字符串,服务器将收到的字符串变换成大写后传回客户。
b)修改上述程序,实现服务器根据客户请求,将服务器端指定的文件可靠地传输给客户。
如果服务器没有指定的文件,服务器将给客户返回一个信息,通知客户其请求文件不存在。
4.实验过程记录(源程序、测试用例、测试结果及心得体会等)
源程序:
(1)服务端:
//
#include<>
#include<>
#include<>
#include
#include
#pragmacomment(lib,"")
usingnamespacestd;
voidOutErr(stringmsg)
{cout<<"错误!
发生在"<fd_setfdread;
intret;
DWORDWINAPIThreadProc(LPVOIDlpParameter)
{
SOCKETc=(SOCKET)lpParameter;
chardata[80];
UINTReciveBytes=0;
FD_ZERO(&fdread);
FD_SET(c,&fdread);
do
{
if((ret=select(0,&fdread,NULL,NULL,NULL))==SOCKET_ERROR)
{
OutErr(string("select"));
break;
}
if(ret>0)
{
if(FD_ISSET(c,&fdread))
{
ReciveBytes=recv(c,data,10,0);
if(ReciveBytes==SOCKET_ERROR)
{
break;
}
cout<<"收到字节数:
"
<<data[ReciveBytes]='\0';
cout<}
}
}while(ReciveBytes>0);
FD_CLR(c,&fdread);
closesocket(c);
return0;
}
intmain()
{
SOCKETserver;
SOCKETclient;
SOCKADDR_INser_addr,cli_addr;
WSADATAwdata;
intcliaddrLen=0;
UINTport=4000;
HANDLEHnd;
DWORDdwThreadID;
if(WSAStartup(MAKEWORD(2,0),&wdata)!
=0)
{
OutErr(string("WSAStartup"));
return1;
}
"");
=AF_INET;
=htons(port);
//if((server=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_IP,NULL,0,1))==INVALID_SOCKET)
if((server=socket(AF_INET,SOCK_STREAM,IPPROTO_IP))==INVALID_SOCKET)
{
OutErr(string("WSASocket"));
return1;
}
if(bind(server,(SOCKADDR*)&ser_addr,sizeof(SOCKADDR))!
=0)
{
OutErr(string("bind"));
return1;
}
if(listen(server,5)!
=0)
{
OutErr(string("listen"));
return1;
}
while
(1)
{
cliaddrLen=sizeof(SOCKADDR);
client=accept(server,(SOCKADDR*)&cli_addr,&cliaddrLen);
cout<<"客户IP:
"<<<",端口:
"<ULONGul=1;
if(ioctlsocket(client,FIONBIO,&ul)==SOCKET_ERROR)
{
OutErr(string("ioctlsocket"));
return1;
}
FD_ZERO(&fdread);//清空集合
FD_SET(client,&fdread);//将C加入到读取集合中
//Hnd=CreateThread(NULL,0,ThreadProc,(LPVOID)client,0,&dwThreadID);
//接收数据
while(TRUE)
{
chardata[11];
intReciveBytes;
//这里阻断程序,知道缓冲区内有可读数据才返回
if((ret=select(0,&fdread,NULL,NULL,NULL))==SOCKET_ERROR)
{
//套接字错误
break;
}
if(ret>0)
{
if(FD_ISSET(client,&fdread))//c中是否属于fdread集合
{
do//循环读取,每次接收10个字符,直到把缓冲区中全部取完
{
ReciveBytes=recv(client,data,10,0);
if(ReciveBytes==SOCKET_ERROR)
{
//SOCKET错误
break;
}
data[ReciveBytes]=0;//加上结束符
cout<<"收到"
<<<"个字节:
\n"
<}while(ReciveBytes>0);
}
}
}//while接收数据
if(Hnd==NULL)
{
CloseHandle(Hnd);
closesocket(client);
}
}
closesocket(server);
WSACleanup();
return0;
}
客户端:
//
#include
#include<>
#include
#pragmacomment(lib,"")
usingnamespacestd;
voidOutErr(stringmsg)
{
cout<<"错误发生:
"
<<}
intmain()
{
SOCKETc;
SOCKADDR_INserver_addr;
WSADATAwsd;
stringmsg;
stringremote_ip;
cout<<"输入对方IP地址:
";
cin>>remote_ip;
if(WSAStartup(MAKEWORD(2,2),&wsd)!
=0)
{
OutErr(string("WSAStartup"));
return1;
}
if((c=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_IP,NULL,0,1))==INVALID_SOCKET)
{
OutErr(string("WSASocket"));
return1;
}
=AF_INET;
=htons(4000);
if(connect(c,(SOCKADDR*)&server_addr,sizeof(SOCKADDR_IN))!
=0)
{
OutErr(string("connect"));
return1;
}
do
{
intSentBytes;
cin>>msg;
if(msg=="exit")break;
if((SentBytes=send(c,(),(),0))==SOCKET_ERROR)
{
OutErr(string("send"));
break;
}
}while
(1);
closesocket(c);
WSACleanup();
return0;
}
测试结果:
心得体会:
通过这次的实验,巩固了我以前基础的java知识,了解Socket类与ServerSocket类的作用与用法,会用一些Socket类与ServerSocket类的重要方法,初步了解java中用来实现客户端TCP操作Socket类,这个类本身使用直接代码通过主机操作系统的本地TCP栈进行通信。