《网络协议编程》实验1
1.实验名称
基于WinSock API的TCP网络程序的编写与分析。
2.实验目的
(1)掌握常用的WinSock API函数。
(2)掌握基于WinSock API函数和TCP协议的网络通信控制台程序的编写方法。3.实验性质与实验课时
(1)实验性质:验证性。
(2)实验课时:2学时。
4.实验环境
计算机局域网、Visual C++6.0
5.实验内容
(1)基于WinSock API函数和TCP协议的daytime网络程序的编写与分析
①在Visual C++6.0中,编写daytime网络通信服务器程序。
②在Visual C++6.0中,编写daytime网络通信客户端程序。
(2)基于WinSock API函数和TCP协议的网络通信控制台程序的编写与分析
①在Visual C++6.0中,编写基于WinSock API函数和TCP协议的网络通信控制台服务器程序。
②在Visual C++6.0中,编写基于WinSock API函数和TCP协议的网络通信控制台客户端程序。
(3)对编写好的网络通信程序在局域网两台不同的电脑上调试。
(4)对编写好的网络通信程序在一台电脑上调试运行。
6.实验步骤
(1)基于WinSock API函数和TCP协议的daytime网络程序的编写与分析
①在Visual C++6.0中,编写daytime网络通信服务器程序。
服务器端程序代码如下:
/***************************************************************
daytime协议的服务器程序分析注解服务器端程序代码如下:
服务器的IP地址:由系统指定
服务器端口号:13
程序名称:daytime.cpp
程序功能:实现由RFC—867定义的daytime协议
命令格式:daytime
***************************************************************/
#include "winsock2.h"
#include "stdio.h"
#include "time.h"
#pragma comment(lib,"WS2_32.lib")
#define MAX_BUFFER 1024 /*服务器缓冲区的最大值为1024个字符*/
//#define NULL 0
#define DAYTIME_SERVER_PORT 13 /*常量表示服务器的端口号为13*/
int main()
{
SOCKET serverFd;
int connectionFd,i=1; /*统计客户请求次数*/
struct sockaddr_in servaddr;
char timebuffer[MAX_BUFFER+1];
time_t currentTime;
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)==SOCKET_ERROR)
{
printf("命令套接口初始化失败\n");
WSACleanup();//终止使用Winsock DLL库,释放系统资源
return-1;
}
serverFd=socket(AF_INET,SOCK_STREAM,0); /*创建服务器端的套接字,三个参数分别代表使用TCP/IP;传输过程使用TCP;不适用其他特殊协议*/
if(serverFd==-1)
{
printf("socket error!\n");
WSACleanup();//终止使用Winsock DLL库,释放系统资源
return(-1);
}
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY); /*将4字节主机字节数顺序转换到网络字节顺序*/
servaddr.sin_port=htons(DAYTIME_SERVER_PORT);/*将4字节主机字节数顺序转换到网络字节顺序*/
if(bind(serverFd,(struct sockaddr *)&servaddr, sizeof(servaddr))==SOCKET_ERROR)/*地址绑定*/
{
printf("bind( ) Failed: %d\n", WSAGetLastError( ));
WSACleanup();//终止使用Winsock DLL库,释放系统资源
return(-1);
}
listen(serverFd,5);/*监听客户端的连接请求,定义最大的链接次数为5次*/
printf("daytime服务器已经启动,正在监听来自客户端的服务请求......\n");//运行界面上提示服务器软件处于启动状态
while(1)
{
connectionFd=accept(serverFd,(struct sockaddr *)NULL,NULL);/*连接建立后将存放在缓冲区的时间发送到客户端*/
if(connectionFd>=0)
{
currentTime=time(NULL);
sprintf(timebuffer,"%s\n",ctime(¤tTime));
printf("已有%d个访问者\n",i++);
send(connectionFd,timebuffer,strlen(timebuffer),0);
closesocket(connectionFd);
}
}
WSACleanup();//终止使用Winsock DLL库,释放系统资源
return(1);
}
②在Visual C++6.0中,编写daytime网络通信客户端程序。
客户端程序代码如下:
/***************************************************************
daytime协议的客户机端程序分析注解客户机端程序代码如下:
服务器的IP地址:在程序中由程序员根据实际情况指定
服务器端口号:13
程序名称:clientdaytime.cpp
程序功能:从daytime服务器获取时间
命令格式:clientdaytime
***************************************************************/
#include "winsock2.h"
#include "stdio.h"
#include "time.h"
#pragma comment(lib,"WS2_32.lib")
#define MAX_BUFFER 1024 /*客户机缓冲区的最大值为1024个字符*/
#define DAYTIME_SERVER_PORT 13 /*常量表示服务器的端口号为13*/
int main()
{
SOCKET connectionFd;
int in;
struct sockaddr_in servaddr;
char timebuffer[MAX_BUFFER+1];
time_t currentTime;
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)==SOCKET_ERROR)
{
printf("命令套接口初始化失败\n");
return-1;
}
connectionFd=socket(AF_INET,SOCK_STREAM,0); /*创建服务器端的套接字,三个参数分别代表使用TCP/IP;传输过程使用TCP;不适用其他特殊协议*/
if(connectionFd==-1)
{
printf("socket error!\n");
return(-1);
}
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(DAYTIME_SERVER_PORT);/*将4字节主机字节数顺序转换到网络字节顺序*/
//inet_addr()函数把字符串形式的IP地址转换为unsiged long型的整数值
servaddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); /*此处设置daytime服务器所在机器IP地址,应根据实际情况确定*/
if(connect(connectionFd,(struct sockaddr
*)&servaddr,sizeof(servaddr))==INV ALID_SOCKET)
{
printf("connect() failed:%d\n",WSAGetLastError());//在界面上输出连接失败的错误提示信息
return(0);
}
while((in=recv(connectionFd,timebuffer,MAX_BUFFER,0))>0)
{
timebuffer[in]=0;
printf("\n%s",timebuffer);
}
closesocket(connectionFd);
WSACleanup();//终止使用Winsock DLL库,释放系统资源
return(1);
}
(2)基于WinSock API函数和TCP协议的网络通信控制台程序的编写与分析
①在Visual C++6.0中,编写基于WinSock API函数和TCP协议的网络通信控制台服务器程序。
主要代码如下:
#include
#include
#include
#pragma comment(lib,"WS2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2,0);
err = WSAStartup( wV ersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 0 )
{
WSACleanup( );
return;
}
SOCKET S;
SOCKET sockSrv;
sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
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));
listen(sockSrv,5);
int len=sizeof(SOCKADDR);
while(1)
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[50];
sprintf(sendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[50];
recv(sockConn,recvBuf,50,0);
printf("%s\n",recvBuf);
closesocket(sockConn);
}
WSACleanup( );
}
②在Visual C++6.0中,编写基于WinSock API函数和TCP协议的网络通信控制台客户端程序。
主要代码如下:
#include
#include
#include
#pragma comment(lib,"WS2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wV ersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
send(sockClient,"你好,我是张三。",strlen("你好,我是张三。")+1,0);
char recvBuf[50];
recv(sockClient,recvBuf,50,0);
printf("%s\n",recvBuf);
closesocket(sockClient);
WSACleanup();
return ;
}
(3)网络通信程序在局域网环境中的测试。
每两个同学为一小组,分别在两台不同的电脑上编写程序,一位同学(称为甲)编写服务器程序,另一位同学(称为乙)则编写客户端程序,注意客户机程序中所写服务器IP 即为甲同学所在电脑的IP地址。程序编写好后,先由甲同学启动服务器程序,然后由乙同学启动客户机程序,验证并观察双方的通信反馈信息。
验证通过后,请甲、乙两位同学交换角色,重新进行验证实验。
(4)网络通信程序在单机上的测试。
二次验证通过后,请每位同学在单机上调试验证,注意客户机程序中所写服务器IP为本机地址,即“127.0.0.1”。
7.实验思考
(1)对于daytime网络通信程序,如果在同一台电脑上,先后两次启动两个服务器程序,使这两个程序均处于运行状态,会出现什么提示信息?为什么会出现这样的提示信息?
(2)实验中碰到其他什么问题?你是如何解决的?