网上第一本以TXT格式的VC++深入详解孙鑫的书.全文全以TXT格式,并每一章节都分了目录,清晰易读
源代码在线查看: 14.6.1 服务器端程序.txt
14.6.1 服务器端程序
首先编写聊天服务器端程序。在一个新的工作区中创建一个空的 Win32 Console
Application类型的应用程序,工程取名为: NetSrv。并为该工程添加一个 CI I源文件:
NetSrv.cpp 0接着,为该工程添加对WinSock库的链接,即在工程设置对话框的Link选项卡上添
加ws2_32.lib文件的链接。然后在NetSrv.cpp文件中添加聊天服务器端程序的实现代码,结果如
例14-5所示。
,
例14-5
#include #include
voìd maìn() {
11加载套接字库
WORD wVersìonRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1,工) ;
err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return;
if ( LOBYTE( wsaData.wVers工on ) ! = 1 I I
H工BYTE( wsaData.wVers工on ) ! = 1 ) (
WSACleanup( );
return;
11创建套接字
SOCKET sockSrv=socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sìn_addr.S_un.S_addr=htonl(INADDR_ANY) ;
addrSrv.sin_famìly=AF一工NET;
addrSrv.sìn-po r t=htons(6000);
11绑定套接字
bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
char recvBuf[100];
char sendBuf[100];
char tempBuf[200];
SOCKADDR_IN addrClient;
ìnt len=sìzeof(SOCKADDR);
552 I胁"
while(l)
{
//等待并接收数据
recvfrorn(sockSrv, recvBuf , 100 , 0 , (SOCKADDR*)&addrClient ,&len);
if('q'==recvBuf[O])
{ sendto (sockSrv, "q" , strlen ("q") +1 , 0, (SOCKADDR*) &addr
Client , len) ; printf("Chat end!\n. ) ; break;
sprintf(ternpBuf,"屯 s say :屯 s", inet_ntoa(addrClient.sin_addr) ,
recvBuf) ; printf ("毡s\丑" , ternpBuf) ; //发送数据
printf("Please input data:\n" ) ;
gets(sendBuf);
sendto(sockSrv, sendBuf , strlen(sendBuf)+l , O, (SOCKADDR*)&addr
Client , len) ;
//关闭套接字
closesocket(sockSrv);
WSACleanup();
在上述例 14-5所示代码中,首先加载套接字库,这可以复制上面程序中已有的代码。
接着,调用 socket函数创建套接字,第一个参数只能是 AF_INET C或 PF_剧ET);因为是基于 UDP
协议的网络应用程序,所以创建的是数据报类型的套接字,即第二个参数应指定为: SOCK_DGRAM;
第三个参数指定为 0。
对于服务器,即接收端来说,需要进行套接字绑定操作,将套接宇绑定到本地机器的一个 F地址
和端口号上。因此,定义一个地址结构 CSOCKADDR_IN)类型的变量=叫"凹,并对其成员赋值。接
着,就调用 bind函数,将套接字与本地地址和端口绑定起来。
接下来,定义了三个字符数组,其中 recvBuf用来保存接收的信息; sendB uf用来保存发送的信
息; tempBuf用来存放中间临时数据。
在接收时需要获取与之通信的对方的地址信息,这是通过 recvfrom函数得到的,但是需要提供
一个地址结构 C SOCKADDR_IN)类型的变量,因此定义了变量: addrClient。接着,定义一个整
型变量: len,并将初始为地址结构体的长度。
然后,进行一个 while循环,保证通信的过程能够地不断进行下去。当循环结束时,调用
closesocket函数关闭套接字,再调用 WSACleanup函数,终止对套接字库的使用。
在 while循环中,因为这是基于 UDP的服务器端程序,即接收端,所以首先应调用 recvfrom函
数接收客户端的数据。接收到数据后,对该数据进行判断,如果第一个字符是 "q飞则表明数据
发送方想要退出聊天过程,于是服务器端程序也给对方发送一个 "q"字符。因为发送方地址 C
addrClient)在调用 recvfrom函数时已经得到了,所以 sendto函数
‘~.... I 553
1.4
中可以直接使用这个地址。数据发送完成之后,调用printf函数打印语句: Chat end!。既然聊
天终止了,那么就要退出循环,因此调用break语旬,终止while循环。
如果recvBuf[O]不是 "q"字符,则说明收到了对方发送的数据,于是将数据格式化,格式化的模
式是:对方IP say对方发迭的数据。其中, addrClient.sin addr字段保存的就是对方的 E地址,
可以利用 inet ntoa函数将该地址转换为点分十进制表示的字符串,而 recvBuf数组中就是接收
到的数据。然后程序将格式化后的字符串放到 tempBuf数组中,之后调用printf函数将这串字符
打印输山。
在输出客户端发送过来的信息后,服务器端应该根据这些信息做出回复,井且回复信息应通过标
准输入设备,即键盘来获取,这可以调用C语言中的函数: gets来实现,其原型声明如下所示:
char *gets( char *buffer );
该函数有一个优点,就是可以从标准输入流中获取一行数据。当通过键盘输入数据并按下回车键
后,输入的数据就可以存放在由参数buffer指定的缓冲区中了。
在得到标准输入流中的数据前,本程序提示: "Please input data: "。当得到数据后,调用 sendto
函数发送该数据,并且与前面的程序一样,多发送一个字节。至此,就完成了发送的过程。
利用 Build菜单命令生成服务器端应用程序。 .