APP下载

使用WINSOCK 实现Windows下网络通信

2013-04-29肖季烈肖维

知识窗·教师版 2013年9期

肖季烈 肖维

摘要:本文介绍了Sockets通信原理,从程序员的角度着重讨论了Windows Sockets的功能扩充,并列举了运用 Windows Sockets实现网络实时通信的一个程序实例。

关键词:Windows Sockets 异步通信 阻塞

一、Socket网络编程原理

Socket是BSD UNIX提供的网络应用编程接口,它采用客户——服务器的通讯机制,使网络客户方和服务器方通过Socket实现网络之间的连接和数据交换。Socket提供了一系列的系统调用,可以实现TCP、UDP、ICMP和IP等多种网络协议之间的通讯。

Socket有三种主要类型:Stream sockets、Datagram sockets 和Raw sockets。Stream socket接口定义了一种可靠的面向连接的服务,实现了无差错、无重复的顺序数据传输,它通过内置的流量控制解决了数据的拥堵,应用程序可以发送任意长度的数据;Datagram socket接口定义了一种无连接的服务,数据通过相互独立的包进行传输,包的传输是无序的,但是不能保证包的正确率。包长度是有限的(隐含长度为8,192字节,最大长度可设为32,768字节);Raw socket接口允许对低层协议(如IP和ICMP)的直接存取,它主要用于实现新网络协议的测试等。

下面,我们通过一个面向连接的传输发生的典型情况来说明Socket网络通信的实现。

从图1中我们可以看出,客户和服务器的关系不是对称的,服务器首先启动,然后在某一时间 从

从图1中我们可以看出,客户与服务器的关系不是对称的,服务器首先启动,然后在某一时间启动客户与服务器的连接。服务器和客户开始都必须用调用socket()建立一个套接字(socket),然后服务器调用bind()将套接字与一个本地网络地址捆绑在一起,再用调用listen()使套接字处于一种被动的准备接收状态,同时规定它的请求队列长度,之后服务器就可以调用accept()来接收连接了。客户在建立套接字之后,就可以通过调用connect()和服务器建立连接。建立连接后,客户和服务器之间就可以通过连接发送和接收数据(调用read()和write())。最后,待数据传送结束,双方调用close()关闭套接字。

二、WINSOCK对Socket的扩充

BSD Socket支持阻塞(blocking)和非阻塞(non_blocking)两种工作方式。在阻塞方式下工作,connect()、accept()、read()和recv()等调用在执行时都处于阻塞状态,直到它成功或出错返回;在非阻塞方式下工作,这些调用是立即返回的,但是必须通过查询才能知道它们是否完成。

WINSOCK对BSD Socket的扩充主要基于消息、对网络事件的异步存取接口上。表1列出了WINSOCK扩充的函数功能。

从表1中我们可以看出,WINSOCK的扩充功能可以分为如下几类:

1.异步选择机制

异步选择函数WSAAsyncSelect()允许应用程序提名一个或多个感兴趣的网络事件,所有非阻塞的网络I/O例程(如send()和resv()),不管它是已经使用,还是即将使用,都可作为WSAAsyncSelect()函数选择的候选。当被提名的网络事件发生时,Windows应用程序的窗口函数将收到一个消息,消息附带的参数指示被提名过的某一网络事件。

2.异步请求例程

异步请求例程允许应用程序用异步方式获取请求的信息,如WSAAsyncGetXByY()类函数允许用户请求异步服务,这些功能在使用标准Berkeley函数时是阻塞的。

3.阻塞处理方法

WINSOCK在调用处于阻塞时会进入一个叫“Hook”的例程,它负责处理Windows消息,使得Windows的消息循环能够继续。WINSOCK还提供了两个函数[WSASetBlockingHook()和WSAUnhookBlockingHook()]让用户能够设置和取消自己的阻塞处理例程。另外,函数WSAIsBlocking()可以检测调用是否阻塞,函数WSACancelBlockingCall()可以取消一个阻塞的调用。

4.出错处理

为了和以后的多线索环境(如Windows/NT)兼容,WINSOCK提供了两个出错处理函数WSAGetLastError()和WSASetLastError()来获取和设置本线索的最近错误号。

5.启动与终止

WINSOCK的应用程序在使用上述WINSOCK函数前,必须先调用WSAStartup()函数对Windows Sockets DLL进行初始化,以协商WINSOCK的版本支持,并分配必要的资源。在应用程序退出之前,应该先调用函数WSAClearnup()终止对Windows Sockets DLL的使用,并释放资源,将有利于下一次使用。

三、网络实时通信的实现

我们来设计一个简单的基于连接的点对点网络实时通信程序:服务器首先启动,它建立套接字之后等待客户的连接;客户在启动后建立套接字,然后和服务器建立连接;连接建立后,客户通过连接给服务器发送一段数据,服务器接收后又将它发送回来,客户再发送,如此循环,直至用户命令客户退出或网络出错;客户关闭连接和套接字后退出,服务器在检测到连接关闭后,关闭套接字自动结束。

我们的实例是UNIX下基于BSD Socket的服务器程序和Windows下基于WINSOCK的客户程序之间的通信。我们先来看客户程序,首先定义几个宏、菜单资源和部分全局变量:

程序1:部分Windows程序源代码(宏、菜单和变量)

#define USERPORT3333/* 用户定义端口号 */

#define IDM_START 101/* “启动”菜单项标志 */

#define IDM_EXIT102 /* “退出”菜单项标志 */

#define UM_SOCK WM_USER+0x100/* 用户定义网络消息 */

ClientMenu MENU/* 客户菜单 */

BEGIN

POPUP "&Server"

BEGIN

MENUITEM "&Start...", IDM_START

MENUITEM "S&top", IDM_STOP

END

END

#include/* 必须包含winsock.h头文件 */

HANDLE hInst;

char server_address[256] = {0}; /* 服务器地址缓冲区 */

char buffer[1024]; /* 接收发送缓冲区 */

char FAR * lpBuffer = &buffer[0];

SOCKET s = 0; /* 套接字 */

struct sockaddr_in dst_addr;/* 目标地址 */

struct hostent *hostaddr; /* 主机地址 */

struct hostent hostnm;

int count = 0;/* 发送接收循环计数器 */

客户程序的窗口主函数很简单,它在注册窗口类、建立窗口后,只是给主窗口函数发送一个用户消息,然后就进入Windows消息处理循环。

程序2:部分Windows程序源代码(窗口主函数)

int PASCAL WinMain( HANDLE hInstance,HANDLE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)

{

HWND hWnd;

MSG msg;

lstrcpy((LPSTR) server_address, lpCmdLine); /* 取主机名字 */

if (!hPrevInstance)

if (!InitApplication(hInstance))

return (FALSE);

hInst = hInstance;

hWnd = CreateWindow("ClientClass","Windows ECHO Client",

WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,

CW_USEDEFAULT,CW_USEDEFAULT,

NULL, NULL, hInstance, NULL);

if (!hWnd)

return (FALSE);

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

/* 给主窗口函数发送WM_USER消息 */

PostMessage(hWnd,WM_USER,(WPARAM) 0, (LPARAM) 0);

while (GetMessage(&msg, NULL, NULL, NULL)) {

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return (msg.wParam);

}

我们用最简单的语句编制一个UNIX下基于BSD SOCKET的服务器程序,它在建立连接后,只负责将收到的数据发回去,在连接断开后,服务器关闭套接字返回。

四、结束语

我们可以看出,WINSOCK提供的异步选择机制使Socket强大的网络编程功能能够在Windows下得到应用。相信随着INTERNET的推广,TCP/IP网络协议的广泛使用,使用WINSOCK编制Windows网络实时通信软件将能得到较大的发展。

参考文献:

[1]孙义等,UNIX环境下的网络程序设计[M].北京:希望公司,1991.

[2]梁振军等,新编TCP/IP协议与计算机网络互联技术[M].北京:希望公司,1992.

(作者单位:江西省萍乡市萍乡广播电视大学)