网络通信软件的设计实验指书.docx
- 文档编号:3017288
- 上传时间:2022-11-17
- 格式:DOCX
- 页数:21
- 大小:26.19KB
网络通信软件的设计实验指书.docx
《网络通信软件的设计实验指书.docx》由会员分享,可在线阅读,更多相关《网络通信软件的设计实验指书.docx(21页珍藏版)》请在冰豆网上搜索。
网络通信软件的设计实验指书
《专业验综合实验》:
网络通信软件的设计
实验目的和要求:
两台微机通信程序的设计;掌握网络通信软件的基本设计方法和技术
主要仪器设备:
两台pc机
软件工具:
C语言
实验内容:
采用两台PC机,采用套接字编程,实现TCP,UDP和IP的协议。
具体要求:
1实验报告的书写要求:
要求写出实验目的,实验内容,实验原理,实验仪器的IP地址,实验结果,并随原始程序。
(原始程序与提供的程序不能完全相同,各同学之间的实验报告不能相同,否则不能通过)。
2要求同学们先看懂资料,并认真编程,调试程序,得出结果。
套接字的基本知识
在VC中进行WINSOCK编程时,需要引入如下两个库文件:
WINSOCK.H(这个是WINSOCKAPI的头文件,WIN2K以上支持WINSOCK2,所以可以用WINSOCK2.H);Ws2_32.lib(WINSOCKAPI连接库文件).
使用方式如下:
#include
#pragmacomment(lib,"ws2_32.lib")
下面我们通过具体的代码演示服务器和客户端的工作流程:
首先,建立一个WSADATA结构,通常用wsaData
WSADATAwsaData;
然后,调用WSAStartup函数,这个函数是连接应用程序与winsock.dll的第一个调用.其中,第一个参数是WINSOCK版本号,第二个参数是指向WSADATA的指针.该函数返回一个INT型值,通过检查这个值来确定初始化是否成功.调用格式如下:
WSAStartup(MAKEWORD(2,2),&wsaData),其中MAKEWORD(2,2)表示使用WINSOCK2版本.wsaData用来存储系统传回的关于WINSOCK的资料.if(iResuit=WSAStartup(MAKEWORD(2,2),&wsaData)!
=0)
{printf("WSAStartupfailed:
%d",GetLastError());//返回值不等与0,说明初始化失败
ExitProcess();//退出程序
}
应用程序在完成对请求的SOCKET库使用后,要调用WSACleanup函数来接触SOCKET库的绑定,并且释放资源.
注意WSAStartup初始化后,必须建立一个SOCKET结构来保存SOCKET句柄.
下面我们建立一个SOCKET.
首先我们建立一个m_socket的SOCKET句柄,接着调用socket()函数,函数返回值保存在m_socket中.我们使用AF_INFE,SOCK_STREAM,IPPROTO_TCP三个参数.第一个表示地址族,AF_INET表示TCP/IP族,第二个表示服务类型,在WINSOCK2中,SOCKET支持以下三种类型:
SOCK_STREAM,流式套接字;SOCK_DGRAM,数据报套接字;SOCK_RAW,原始套接字
第三个参数表示协议:
IPPROTO_UDP,UDP协议用于无连接数据报套接字
IPPROTO_TCPTCP协议用于流式套接字
IPPROTO_ICMPICMP协议用于原始套接字
m_socket=socket(AF_INFE,SOCK_STREAM,IPPROTO_TCP);//创建TCP协议
以下代码用于检查返回值是否有错误:
if(m_scoket==INVALID_SOCKET)
{prinrf("Erroratsocket():
%d\n",GetLastError());
WSACleanup();//释放资源
return;
}
说明,如果socket()调用失败,他将返回INVALID_SOCKET.
为了服务器能接受一个连接,他必须绑定一个网络地址,下面的代码展示如何绑定一个已经初始化的IP和端口的Socket.客户端程序用这个
IP地址和端口来连接服务器.
sockaddr_inservice;
service.sin_family=AF_INET;//INTERNET地址族
service.sin_addr.s_addr=inet_addr("127.0.0.1");//将要绑定的本地IP地址
service.sin_port=htons(27015);//27015将要绑定的端口
下面我们调用BIND函数,把SOCKET和SOCKADDR以参数的形式传入,并检查错误.
if(bind(m_socket,(SOCKADDR*)&SERVICE,sizeof(service))==SOCKET_ERROR)
{
printf("bind()failed.\n");
closesocket(m_socket);
return;
}
当绑定完成后,服务器必须建立一个监听队列,以接受客户端的请求.listen()使服务器进入监听状态,该函数调用成功返回0,否则返回
SOCKET_ERROR.代码如下:
if(listen(m_socket,1)==SOCKET-ERROR)
{
printf("errorlisteningonsocket.\n");
}
服务器端调用完LISTEN()后,如果此时客户端调用CONNECT()函数,服务器端必须在调用ACCEPT().这样服务器和客户端才算正式完成通信程序的
连接动作.
一旦服务器开始监听,我们就要指定一个句柄来表示利用ACCEPT()函数接受的连接,这个句柄是用来发送和接受数据的表示.建立一个SOCKET句柄
SocketAcceptSocket然后利用无限循环来检测是否有连接传入.一但有连接请求,ACCEPT()函数就会被调用,并且返回这次连接的句柄.
printf("waitongforaclienttoconnect...\n");
while
(1)
{
AcceptSocket=SOCKET_ERROR;
while(AcceptSocket==SOCKET_ERROR)
{
AcceptSocket=accept(m_socket,NULL,NULL);
}
}
下面看客户端端代码:
sockaddr_inclientService;
clientService.sin_family=AF_INET;//INTERNET地址族
clientService.sin_addr.s_addr=inet_addr("127.0.0.1");//将要绑定的本地IP地址
clientService.sin_port=htons(27015);//27015将要绑定的端口
下面调用CONNECT()函数:
if(connect(m_socket,(SOCKADDR*)&clientService,sizeof(clientService))==SOCKET_ERROR)
{
printf("Failedtoconnect.\n");
WSACleanup();
return;
}//如果调用失败清理退出
//调用成功继续读写数据
下面我们介绍数据交换.
send():
intsend
{
SOCKETs,//指定发送端套接字
constcharFAR?
*buf,//指明一个存放应用程序要发送的数据的缓冲区
intlen,//实际要发送的数据字节数
intflags//一般设置为0
};
C/S都用SEND函数向TCP连接的另一端发送数据.
recv():
intrecv
{
SOCKETs,//指定发送端套接字
charFAR?
*buf,//指明一个缓冲区存放RECC受到的数据
intlen,//指明BUF的长度
intflags//一般设置为0
};
绑定socket后用listen函数去监听,如果有连接请求就把该请求放到等待队列里,等待accept函数来接收。
一旦accept接收成功就创建一个新的socket来处理与client的通讯。
accept()函数
准备好了,系统调用accept()会有点古怪的地方的!
你可以想象发生这样的事情:
有人从很远的地方通过一个你在侦听(listen())的端口连接(connect())到你的机器。
它的连接将加入到等待接受(accept())的队列中。
你调用accept()告诉它你有空闲的连接。
它将返回一个新的套接字文件描述符!
这样你就有两个套接字了,原来的一个还在侦听你的那个端口,新的在准备发送(send())和接收(recv())数据。
这就是这个过程!
函数是这样定义的:
#include
intaccept(intsockfd,void*addr,int*addrlen);
sockfd相当简单,是和isten()中一样的套接字描述符。
addr是个指向局部的数据结构sockaddr_in的指针。
这是要求接入的信息所要去的地方(你可以测定哪个地址在哪个端口呼叫你)。
在它的地址传递给accept之前,addrlen是个局部的整形变量,设置为sizeof(structsockaddr_in)
accept将不会将多余的字节给addr。
如果你放入的少些,那么它会通过改变addrlen的值反映出来。
同样,在错误时返回-1,并设置全局错误变量errno。
现在是你应该熟悉的代码片段。
#include
#include
#include
#defineMYPORT3490/*用户接入端口*/
#defineBACKLOG10/*多少等待连接控制*/
main()
{
intsockfd,new_fd;/*listenonsock_fd,newconnectiononnew_fd*/
structsockaddr_inmy_addr;/*地址信息*/
structsockaddr_intheir_addr;/*connector'saddressinformation*/
intsin_size;
/*don'tforgetyourerrorcheckingforthesecalls:
*/
sockfd=socket(AF_INET,SOCK_STREAM,0);/*错误检查*/
my_addr.sin_family=AF_INET;/*hostbyteorder*/
my_addr.sin_port=htons(MYPORT);/*short,networkbyteorder*/
my_addr.sin_addr.s_addr=INADDR_ANY;/*auto-fillwithmyIP*/
bzero(&(my_addr.sin_zero);/*zerotherestofthestruct*/
bind(sockfd,(structsockaddr*)&my_addr,sizeof(structsockaddr));
listen(sockfd,BACKLOG);
sin_size=sizeof(structsocka
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 通信 软件 设计 实验