实验三WINSOCK套接字编程实验报告.docx
《实验三WINSOCK套接字编程实验报告.docx》由会员分享,可在线阅读,更多相关《实验三WINSOCK套接字编程实验报告.docx(9页珍藏版)》请在冰豆网上搜索。
实验三WINSOCK套接字编程实验报告
实验三、WINSOC套接字编程实验报告
一、实验目的:
用C或JAVA语言编写客户端、服务器程序,实现基于TCP或UDP的网络通信数据传输服务,熟悉基于TCP或UDP的Socket编程原理。
二、实验环境:
建立在TCP/IP网络体系结构之上计算机网络实验环境。
各计算机除了安装TCP/IP软件外,还安装了TCP/IP开发系统。
计算机具备Windows环境中套接字socket的编程接口功能,可为用户提供全网范围的进程通信功能。
三、实验步骤
(1)运行指导书中给出的参考程序,分析实验结果,并回答问题
(1)
-(3)
(2)根据给定参考程序修改代码,完善修改服务器和客户端的功能。
并回答问题(4)-(5)
四、实验结果分析
(1)为什么在服务器和客户端要包含文件?
答:
因为无论服务器端程序还是客户端程序都要建立socket,如果不包含文件就无法创建socket,没有socket服务器与客户端就无法通信。
(2)为什么在服务器和客户端程序中要加入#pragmacomment(lib,"")语句,如果不加会出现什么问题?
答:
因为要告诉链接器生成exe时链接这个库中的函数。
当然也可
以通过别的方法告诉链接器。
就是让程序在链接的时候将这个文件链接进来,如果没有这句话,你也没有在工程的ClassWizerd
选项卡的Link选项卡中加入这个文件的时候,链接就会提醒某些函数没有被链接到!
有了这个文件,一般就是提供某一些函数的实现代码,只不过不是以字符形式存储的!
(3)为什么在服务器和客户端程序中要使用WSAStartup函数,如果不用,程序会有什么问题?
答:
WSADATAwsaData;
wVersionRequested=MAKEWORD(2,2);
err=WSAStartup(wVersionRequested,&wsaData);
第一个参数是版本号即版本,第二个参数返回socket的版本
信息操作系统利用第二个参数返回请求的Socket的版本信息。
当一个应用程序调用Startup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。
以后应用程序就可以调用所请求的Socket库中的其它
Socket函数了。
为了在应用程序当中调用任何一个WinsockAPI函数,首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化,因此需要调用WSAStartup函数。
使用Socket的程序在使用Socket之前必须调用WSAStartup函数,如果不调用后面socket无法执行。
(4)
(修
修改后的程序完成实现了什么功能,附上修改后的源代码。
改或填加的代码用波浪线标注,并填加注释),并附上实验截图客户端:
实现本地ip自动检测,并且由用户键入想要通信的服务器地址,实现大小写互相转换后送达服务端。
源代码如下:
#include""
#include<>
#inc|ude^<>.
#inelude<>
#inelude<>
#inelude<>
#inelude<>
#pragmacomment(lib,"")
#definePORT3490/*客户机连接远程主机的端口*/
#defineMAXDATASIZE100/*每次可以接收的最大字节*/
#.defineTRUEJ..
int_tmain(intargc,_TCHAR*argv[]){
WORD
WSADATAintSOCKET
wVersionRequested;wsaData;
err=0,rval=0;
fd;
servaddr;hp;
buf[1024]=""
structsockaddr_instructhostent*intlen,i;
char
charn.ame.[255])*i.p>toi.p[?
.0.1,no;...
/*进行本地IP检测*/
一PHOSTENThostinfo;,
w八/ersionRequested=R力AKE\八/ORD(2,2);
err=WSAStartup(wVersionRequested,&wsaData);
讦(\A/SAStartiip(MAKEW/ORD(2,0),&wsaData)==0){
if(gethostname.(name,sizeof(name))==0){—
if((hostinfcu=.g£ihosbyname(name)l=NULL)-{
ip=inetntoa(*(structinaddr*)*hostinfo->haddrlist);
K
“―——一
WSACleanup();
printf("本机IP地址为%s,输入服务器IP地址\n",ip);
gets(toip);
/*循环保证多次向服务器端发送信息*/
do{
if(err!
=0)
return-1;
if((fd=socket(AF」NET,SOCK_STREAM,0))<0)
{
printf("无法创建套接口!
");exit
(2);
}
=AF_INET;
=htons(PORT);
"");
memset,0,sizeof);
//和服务器创建连接
rval=connect(fd,(sockaddr*)&servaddr,sizeof(servaddr));if(rval<0)
{〃创建连接失败
printf("无法连接!
");exit(3);
}
else
{memset(buf,0,1024);
printf("请输入:
");scanf("%s",&buf);
//实现大小写字母的相互转换/
l£D=sirJenbf,
for(i=0;iif(isalpha(buf[i]))
—{■
buf[i]A三32;一
〃向服务器发送信息
rval=send(fd,buf,strlen(buf)+1,0);
if(rval<0)
printf("警告!
!
!
输入错误!
");
}closesocket(fd);
}while(TRUE),一’
exit(5);
return0;
}
|本机tP地址为192.168.2OCL2町输入服务器tP地址
192.168.200.24
请输入:
ABCDiEFGhijklinn
请输入;OpQRsT
请输入:
uUwXyZ
请输入:
HELLOworld
服务端:
实现接受信息的时间控制,能显示出接受信息的具体时间,源代码如下:
#inelude<>
#inelude<>
#pragmaeomment(lib,"")
#defineMYPORT
3490
#defineBACKLOG
#defineSERVERIPADDR
SOCKET
int
10
""/*服务器的IP地址*/soek,msgsoek;
length=0;
/*定义用户连接端口*/
/*多少等待连接控制*/
structsoekaddrin
structsoekaddr
ehar
int
WORD
WSADATA
server;
tepaddr;
buf[1024]三”",bufree[1024]三"”;rval=0,len三0,err=0;
wVersionRequested;
wsaData;
#inelude""#inelude<>#inelude<>#inelude<>#inelude<>
}
printf(”无法连接”);
iime(&timep)4p=geaJtjm.e(&timep);
tim,ettimep;structIm瓷p;.
/*计时操作*/voiduserlnput(void*)
memset(bufree,0,sizeof(bufree)):
if((rval=reev(msgsoek,bufree,sizeof(buf),0)<0)).
{
printf("\n%d;%d:
%dn%s\n",p->tmhour,D->tmmin,p->tmsec,bufrec);
}
—}while
(1);
}
int_tmain(intargc,_TCHAR*argv[])
{
/*指定socket版本,否则创建socket失败,即使创建socket返回值不为-1,但是bind时会失败*/
wVersionRequested=MAKEWORD(2,2);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!
=0)
return-1;
/*建立套接字*/
sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("openingstreamsocket");
exit
(1);
}
/*使用任意端口命名套接字*/
=AF_INET;
=htons(MYPORT);
=inet_addr(SERVER_IP_ADDR);
memset,0,sizeof);
〃将服务器地址与socket绑定在一起
rval=bind(sock,(structsockaddr*)&server,sizeof(server));
if(rval<0)
{
perror("bindingstreamsocket");
exit
(1);
}
//找出指定的端口号并打印出来
length=sizeof(server);
if(getsockname(sock,(structsockaddr*)&server,&length)<0)
{
perror("gettingsocketname");
exit
(1);
}
printf("套接口号为:
%d\n",ntohs);
//开始接收连接,最大请求数为
listen(sock,5);\/
len=sizeof(structsockaddr);
do
{msgsock=accept(sock,(structsockaddr*)&tcpaddr,(int*)&len);
if(msgsock==-1)
perror("accept");
else
{memset(buf,0,sizeof(buf));
if((rval=recv(msgsock,buf,sizeof(buf),0)<0))
perror("readingstreammessage");
if(rval==0)
{
time(&jtimep);p=localtime(&timep);
/printf("\n%d:
%d:
%d\n%s\n",p->tm二hour,p-_>tm二minp->t