网络通信软件的设计实验指书Word文档格式.docx
- 文档编号:15928264
- 上传时间:2022-11-17
- 格式:DOCX
- 页数:21
- 大小:26.19KB
网络通信软件的设计实验指书Word文档格式.docx
《网络通信软件的设计实验指书Word文档格式.docx》由会员分享,可在线阅读,更多相关《网络通信软件的设计实验指书Word文档格式.docx(21页珍藏版)》请在冰豆网上搜索。
在VC中进行WINSOCK编程时,需要引入如下两个库文件:
WINSOCK.H(这个是WINSOCKAPI的头文件,WIN2K以上支持WINSOCK2,所以可以用WINSOCK2.H);
Ws2_32.lib(WINSOCKAPI连接库文件).
使用方式如下:
#include<
winsock.h>
#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"
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);
当绑定完成后,服务器必须建立一个监听队列,以接受客户端的请求.listen()使服务器进入监听状态,该函数调用成功返回0,否则返回
SOCKET_ERROR.代码如下:
if(listen(m_socket,1)==SOCKET-ERROR)
errorlisteningonsocket.\n"
服务器端调用完LISTEN()后,如果此时客户端调用CONNECT()函数,服务器端必须在调用ACCEPT().这样服务器和客户端才算正式完成通信程序的
连接动作.
一旦服务器开始监听,我们就要指定一个句柄来表示利用ACCEPT()函数接受的连接,这个句柄是用来发送和接受数据的表示.建立一个SOCKET句柄
SocketAcceptSocket然后利用无限循环来检测是否有连接传入.一但有连接请求,ACCEPT()函数就会被调用,并且返回这次连接的句柄.
waitongforaclienttoconnect...\n"
while
(1)
AcceptSocket=SOCKET_ERROR;
while(AcceptSocket==SOCKET_ERROR)
AcceptSocket=accept(m_socket,NULL,NULL);
下面看客户端端代码:
sockaddr_inclientService;
clientService.sin_family=AF_INET;
clientService.sin_addr.s_addr=inet_addr("
clientService.sin_port=htons(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
charFAR?
*buf,//指明一个缓冲区存放RECC受到的数据
intlen,//指明BUF的长度
绑定socket后用listen函数去监听,如果有连接请求就把该请求放到等待队列里,等待accept函数来接收。
一旦accept接收成功就创建一个新的socket来处理与client的通讯。
accept()函数
准备好了,系统调用accept()会有点古怪的地方的!
你可以想象发生这样的事情:
有人从很远的地方通过一个你在侦听(listen())的端口连接(connect())到你的机器。
它的连接将加入到等待接受(accept())的队列中。
你调用accept()告诉它你有空闲的连接。
它将返回一个新的套接字文件描述符!
这样你就有两个套接字了,原来的一个还在侦听你的那个端口,新的在准备发送(send())和接收(recv())数据。
这就是这个过程!
函数是这样定义的:
#include<
sys/socket.h>
intaccept(intsockfd,void*addr,int*addrlen);
sockfd相当简单,是和isten()中一样的套接字描述符。
addr是个指向局部的数据结构sockaddr_in的指针。
这是要求接入的信息所要去的地方(你可以测定哪个地址在哪个端口呼叫你)。
在它的地址传递给accept之前,addrlen是个局部的整形变量,设置为sizeof(structsockaddr_in)
accept将不会将多余的字节给addr。
如果你放入的少些,那么它会通过改变addrlen的值反映出来。
同样,在错误时返回-1,并设置全局错误变量errno。
现在是你应该熟悉的代码片段。
string.h>
sys/types.h>
#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文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 通信 软件 设计 实验