网络安全 频道

一个精巧的应用程序实例-wshout

一个精巧的应用程序实例-wshout

我们通过一个经过精心选择的例子,进一步讨论一下Windows Sockets编程技术。例如如何编制客户机或服务器程序,如何应用TCP有连接服务(流式套接口)或UDP无连接服务(数据报套接口),如何进行阻塞或非阻塞方式的套接口操作等等,这些都是经常碰到的问题。接下来要介绍的wshout程序,可以通过灵活地设置不同选项来达到上述应用情况的任意组合,从而基本覆盖了应用Windows Sockets编程所可能碰到的问题,具有很好的研究参考价值。

由于该程序思路清晰,结构精良,所以我们不打算很详细地剖析每一个语句,而只是简要介绍一下整个程序的逻辑结构,并在源程序中加入适当的注释。我们相信,任何具有基本C语言和Windows编程经验的读者,都能很轻松地读懂绝大部分内容。经过仔细咀嚼和推敲后,更能得到一些编写优质程序的灵感。

该程序在FTP公司的PCTCP支撑环境下调试通过,不过只要读者拥有任何符合Windows Sockets 1.1规范的实现,也能顺利执行该程序。

源程序目录

1. wshout.c wshout主程序

2. wshout.h wshout头文件

3. wshout.rc wshout资源文件

4. ushout.c UDP客户机程序

5. ulisten.c UDP服务器程序

6. tshout.c TCP客户机程序

7. tlisten.c TCP服务器程序

8. errno.c 获取WSAE*错误描述字符串程序

9. resolve.c 客户机/服务器启动程序


在编译本程序时,笔者用的是BC3.1,只需做一个PRJ工程文件,将上述.c文件及winsock.lib包括进来就行了。请注意winsock.h应在include目录或当前目录中,winsock.lib可利用winsock.dll通过implib工具来建立。如果读者使用其他的编译器,可自行作相应的调整,在此不再赘述。

1. wshout.c清单
CODE:
/*

* 文件名: WSHOUT.C

*/


/* MSC Include files: */

#include <stdio.h>

#include <io.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>


#include "wshout.h"


#define MAJOR_VERSION 1

#define MINOR_VERSION 2

#define WSA_MAKEWORD(x,y) ((y) * 256 + (x)) /* HI:Minor, LO:Major */


HANDLE hInst; /* 进程实例句柄 */

HWND hOurWnd; /* 主窗口句柄 */

HWND hMainDlg; /* 主对话框句柄 */


int ret; /* 工作变量 */

char prbuf[PRBUF_LEN]; /* 用于显示文本的工作缓冲区 */


SOCKET sd; /* 用于监听连接的套接口描述字 */

long temporary_option = 0L; /* 缺省为阻塞模式 */

long blocking_option = 0L; /* 阻塞模式的全局标识 */

int run_cancelled = 0; /* 指示何时按下了取消按钮 */

int len = 1024; /* 一次写的字节数 */

BOOL running = FALSE; /* 程序的运行状态 */

const int iTCP = 1; /* 指定为TCP Shout */

const int iUDP = 2; /* 指定为UDP Shout */

int iProto = 1; /* 缺省为TCP Shout */

int iPortNo = SOCK_SHOUT;

int temporary_protocol = 1; /* 在Settings()中使用 */

int iShout = 1;

int iListen = 2;

int iClientOrServer = 1; /* 缺省为Shout(客户机) */

int tClientOrServer = 1; /* 在Settings()中使用 */

char HostModeBuf[20];/* 保存模式字符串 */

WORD VersionReqd;

LPWSADATA lpmyWSAData;


int PASCAL

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

{


HWND hWnd;

MSG msg;

BOOL InitApp(HANDLE);


if (!hPrevInstance)

if (!InitApp(hInstance))

return (NULL);


hInst = hInstance;


hWnd = CreateWindow("MainMenu",

"Windows Shout",

WS_OVERLAPPEDWINDOW | WS_SYSMENU | WS_MINIMIZEBOX,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

NULL,

NULL,

hInstance,

NULL);


if (!hWnd)

return (NULL);


hOurWnd = hWnd;


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

TranslateMessage(&msg); /* 翻译虚拟键码 */

DispatchMessage(&msg);

}


return (msg.wParam);

}


BOOL InitApp(HANDLE hInstance)

{

HANDLE hMemory;

PWNDCLASS pWndClass;

BOOL bSuccess;


hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));

pWndClass = (PWNDCLASS) LocalLock(hMemory);

pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);

pWndClass->hIcon = LoadIcon(hInstance, (LPSTR) "SHOUT");

pWndClass->lpszMenuName = (LPSTR) "MainMenu";

pWndClass->lpszClassName = (LPSTR) "MainMenu";

pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);

pWndClass->hInstance = hInstance;

pWndClass->style = NULL;

pWndClass->lpfnWndProc = ShoutWndProc;


bSuccess = RegisterClass(pWndClass);


LocalUnlock(hMemory);

LocalFree(hMemory);

return (bSuccess);

}


long FAR PASCAL ShoutWndProc(HWND hWnd, WORD message,WORD wParam, LONG lParam)

{
0
相关文章