WinSock文件传输例程求购!(100分)

  • 主题发起人 主题发起人 Opasmcing
  • 开始时间 开始时间
[h4]下面是一个从winsocket编程规范中节选的例程,但是C语言用的,改造一下就能适合delphi.更详细的资料可以去这里下载:
http://www.lingphi.com
[/h4]
3.4 另一个精巧的应用程序实例-wshout

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

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

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


 

3.4.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工具来建立。如果读者使用其他的编译器,可自行作相应的调整,在此不再赘述。

 

3.4.2 程序逻辑结构




 

3.4.3 源程序清单及注释

3.4.3.1 wshout.c清单

/*

* 文件名: 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(&amp;msg, NULL, NULL, NULL)) {

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

DispatchMessage(&amp;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)

{

FARPROC lpDialogBoxProc;


switch (message){

case WM_CREATE:


/* Put up the dialog box */

lpDialogBoxProc = MakeProcInstance(DialogProc, hInst);

DialogBox (hInst, (LPSTR) "MainDialog", hWnd, lpDialogBoxProc) ;

FreeProcInstance(lpDialogBoxProc);

PostMessage(hWnd, WM_DESTROY, 0, 0L);

break;


case WM_DESTROY:

PostQuitMessage(0);

break;


default:

return(DefWindowProc(hWnd, message, wParam, lParam));

}

return NULL;


}


 

BOOL FAR PASCAL DialogProc(HWND hOurDlg, WORD message, WORD wParam, LONG lParam)

{

FARPROC lpProcAbout;

FARPROC lpProcSettings;

long lret;

WORD wMajorVersion, wMinorVersion;

char hostnm[64]; /* 包含主机名的工作缓冲区 */


switch (message) {

case WM_INITDIALOG:

/* 选择缺省主机 */

SetDlgItemText(hOurDlg, IDD_HNAME, "");

SendDlgItemMessage(hOurDlg, /* 对话框句柄 */

IDD_HNAME, /* 向何处发送msg */

EM_SETSEL, /* 选择字符 */

NULL, /* 附加信息 */

MAKELONG(0, 0x7fff)); /* 全部内容 */

SetFocus(GetDlgItem(hOurDlg, IDD_HNAME));


/* 初始化 */

hMainDlg = hOurDlg; /* 保存自己的窗口句柄 */

SetDlgItemText(hOurDlg, IDD_COHOST,"Shout to:");

wMajorVersion = MAJOR_VERSION;

wMinorVersion = MINOR_VERSION;

VersionReqd=WSA_MAKEWORD(wMajorVersion, wMinorVersion);


lpmyWSAData = (LPWSADATA)_calloc(1, sizeof(WSADATA));


ret = WSAStartup(VersionReqd, lpmyWSAData);


if (ret != 0){

wshout_err (hOurDlg, WSAGetLastError(), "WSAStartup()");

}


return (TRUE);


case WM_CLOSE:

PostMessage(hOurDlg, WM_COMMAND, IDM_EXIT, 0L);

break;


case WM_SYSCOMMAND:

SendMessage(hOurWnd, message, wParam, lParam);

break;


case WM_COMMAND:

switch (wParam) {

case IDD_CONNECT: /* 按下连接按钮 */

case IDM_START: /* 选择了Start菜单项 */

run_cancelled = FALSE;

/* 不能重入 */

if (running){

MessageBox(hOurWnd,"Shout is already running !",

"Shout", MB_OK | MB_APPLMODAL | MB_ICONEXCLAMATION);

return FALSE;

}

ClearBoxes(hOurDlg);

running = TRUE;


if (iClientOrServer == iShout) {

/* 确保有主机名 */

if (GetDlgItemText (hOurDlg, IDD_HNAME, hostnm, 80) < 2) {

MessageBeep(0);

SetDlgItemText(hOurDlg,

IDD_COMMENT,"No hostname specified");

running = FALSE;

break;

}

sd = ResolveAndConnectHost((char FAR *)hostnm,hOurDlg,iProto,

iPortNo);

if (sd == SOCKET_ERROR) {/* 无法创建套接口 */

running = FALSE;

break;

}

}

else {

sd = GetSocketAndBind(hOurDlg, iProto, iPortNo);

if (sd == SOCKET_ERROR) {

running = FALSE;

break;

}

}


/* Set the I/O mode of the socket */

if (blocking_option) {

lret = 1L; /* 非阻塞模式 */

ioctlsocket(sd, FIONBIO, (u_long FAR *) &amp;lret);

}

else {

lret = 0L; /* 阻塞模式 */

ioctlsocket(sd, FIONBIO, (u_long FAR *) &amp;lret);

}


if (iClientOrServer == iShout) { /* SHOUT */

/* 产生数据并写入套接口 */

if (iProto == iTCP)

lret = TWriteData(sd, hOurDlg, len);

else /* UDP */

lret = UWriteData(sd, hOurDlg, len);

}

else { /* LISTEN */

if (iProto == iTCP)

lret = TReadData(sd,hOurDlg, len);

else /* UDP */

lret = UReadData(sd,hOurDlg, len);

}


closesocket(sd);

running = FALSE;

break;


case IDD_CANCEL:

if (running) {

/* 停止 */

ret = WSACancelBlockingCall();

run_cancelled = TRUE;

if (ret == SOCKET_ERROR) {

/* WSANOTINITIALISED or WSAENETDOWN or WSAEINVAL */

if (h_errno == WSAENETDOWN) {

/* Watch out for hAcceptSock! */

/* close what is left of the connection */

closesocket(sd);

}

}

}

break;


case IDM_EXIT:

ret = WSACleanup();

if (ret == SOCKET_ERROR &amp;&amp; h_errno == WSAEINPROGRESS){

MessageBox(hOurWnd,

"Data transfer in progress./nStop transfer first.",

"WndProc()", MB_OK | MB_APPLMODAL|MB_ICONINFORMATION);

break; /* 一个套接口正处于阻塞状态 */

}


_free((char NEAR *) lpmyWSAData);

EndDialog(hOurDlg, TRUE) ; /* 退出 */

break;


case IDM_ABOUT:

lpProcAbout = MakeProcInstance(About, hInst);

DialogBox(hInst, "AboutBox", hOurDlg, lpProcAbout);

FreeProcInstance(lpProcAbout);

break;


case IDM_SETTINGS:

lpProcSettings = MakeProcInstance(Settings, hInst);

DialogBox(hInst, "SettingsDialog", hOurDlg, lpProcSettings);

FreeProcInstance(lpProcSettings);

break;


default:

break;


} /* switch (wParam) */

break;

} /* switch (message) */

return FALSE;

}


 

/* 此函数处理About对话框 */

BOOL FAR PASCAL About(HWND hDlg, WORD message, WORD wParam, LONG lParam)

{

char tempBuf[15];


switch (message) {

case WM_INITDIALOG:

SetDlgItemText(hDlg, IDA_COPYRIGHT,(LPSTR)lpmyWSAData->szDescription);


wsprintf(tempBuf, "%d.%2d/n",MAJOR_VERSION, MINOR_VERSION);

SetDlgItemText(hDlg, IDA_APP_VERSION, (LPSTR) tempBuf);


wsprintf(tempBuf, "%d.%2d/n",

lpmyWSAData->wVersion%256,lpmyWSAData->wVersion/256);

SetDlgItemText (hDlg, IDA_DLL_VERSION, (LPSTR) tempBuf);

return (FALSE);


case WM_COMMAND:

if (wParam == IDOK

|| wParam == IDCANCEL) {

EndDialog(hDlg, TRUE);

return (TRUE);

}

break;

}

return (FALSE);

}


/* 此函数处理Settings 对话框 */

BOOL FAR PASCAL Settings(HWND hDlg, WORD message, WORD wParam, LONG lParam)

{

int buffer_len = len;

int port_no = iPortNo;


switch (message) {

case WM_INITDIALOG:

/* Select a default send() buffer length */

SetDlgItemInt(hDlg, IDS_BUFFLEN, len, 0);


/* Select a default port number */

SetDlgItemInt(hDlg, IDS_PORTNO, iPortNo, 0);


if (iClientOrServer == iShout) /* 程序类型 */

CheckThisProgBoxOn(hDlg, IDS_CLIENT);

else

CheckThisProgBoxOn(hDlg, IDS_SERVER);


if (iProto == iTCP) /* 协议类型 */

CheckThisProtoBoxOn(hDlg, IDS_TCP);

else

CheckThisProtoBoxOn(hDlg, IDS_UDP);


if (!blocking_option) /* 阻塞模式 */

CheckThisBoxOn(hDlg, IDS_BLOCK);

else

CheckThisBoxOn(hDlg, IDS_NOBLOCK);


SendDlgItemMessage(hDlg, /* dialog handle */

IDS_PORTNO, /* where to send msg */

EM_SETSEL, /* select characters */

NULL, /* additional info */

MAKELONG(0, 0x7fff)); /* entire contents */


SendDlgItemMessage(hDlg, /* dialog handle */

IDS_BUFFLEN, /* where to send msg */

EM_SETSEL, /* select characters */

NULL, /* additional info */

MAKELONG(0, 0x7fff)); /* entire contents */

SetFocus(GetDlgItem(hDlg, IDS_BUFFLEN));

return (TRUE);


case WM_COMMAND:

switch (wParam){

case IDS_CLIENT:

/* USer has set to Shout */

CheckThisProgBoxOn(hDlg, IDS_CLIENT);

tClientOrServer = iShout;

SetDlgItemText(hMainDlg, IDD_COHOST,"Foreign host:");

SetDlgItemText(hMainDlg, IDD_HNAME,"");

break;

case IDS_SERVER:

/* USer has set to Listen */

CheckThisProgBoxOn(hDlg, IDS_SERVER);

tClientOrServer = iListen;

SetDlgItemText(hMainDlg, IDD_COHOST,"Listening to:");

SetDlgItemText(hMainDlg, IDD_HNAME,"[Hit 'Start']");

break;

case IDS_TCP:

/* USer has set to TCP */

CheckThisProtoBoxOn(hDlg, IDS_TCP);

temporary_protocol = iTCP;

break;

case IDS_UDP:

/* USer has set to UDP */

CheckThisProtoBoxOn(hDlg, IDS_UDP);

temporary_protocol = iUDP;

break;

case IDS_BLOCK:

/* User has set to blocking mode */

CheckThisBoxOn(hDlg, IDS_BLOCK);

temporary_option = 0L;

break;

case IDS_NOBLOCK:

/* User has set to nonblocking mode */

CheckThisBoxOn(hDlg, IDS_NOBLOCK);

temporary_option = 1L;

break;

case IDOK:

/* 用户已完成对设置的修改 */

buffer_len = GetDlgItemInt(hDlg, IDS_BUFFLEN, NULL, 0);

if (buffer_len == 0 || buffer_len > 8192) {

MessageBox(hOurWnd, "Buffer length must be between 1 and 8K",

"Settings()",

MB_OK | MB_APPLMODAL | MB_ICONSTOP);

return (FALSE);

}


port_no = GetDlgItemInt(hDlg, IDS_PORTNO, NULL, 0);

if (port_no == 0) {

MessageBox(hDlg, "Port number must be between 0 and 65,535",

"Settings()",

MB_OK | MB_APPLMODAL | MB_ICONSTOP);

return (FALSE);

}

len = buffer_len;

iPortNo = port_no;

blocking_option = temporary_option;

iProto = temporary_protocol;

iClientOrServer = tClientOrServer;


case IDCANCEL:

/* 用户不想改变设置 */

EndDialog(hDlg, TRUE);

return (TRUE);


default:

break;

}


default:

break;

}

return (FALSE);

}


void

CheckThisBoxOn(HWND hDlg, int ButtonID)

{

switch (ButtonID) {

case IDS_BLOCK:

CheckDlgButton(hDlg, IDS_BLOCK, 1);

CheckDlgButton(hDlg, IDS_NOBLOCK, 0);

break;

case IDS_NOBLOCK:

CheckDlgButton(hDlg, IDS_BLOCK, 0);

CheckDlgButton(hDlg, IDS_NOBLOCK, 1);

break;

default:

break;

}

return;

}


void

CheckThisProtoBoxOn(HWND hDlg, int ButtonID)

{

switch (ButtonID) {

case IDS_TCP:

CheckDlgButton(hDlg, IDS_TCP, 1);

CheckDlgButton(hDlg, IDS_UDP, 0);

break;

case IDS_UDP:

CheckDlgButton(hDlg, IDS_TCP, 0);

CheckDlgButton(hDlg, IDS_UDP, 1);

break;

default:

break;

}

return;

}


void

CheckThisProgBoxOn(HWND hDlg, int ButtonID)

{

switch (ButtonID) {

case IDS_CLIENT: /* Shout */

CheckDlgButton(hDlg, IDS_CLIENT, 1);

CheckDlgButton(hDlg, IDS_SERVER, 0);

break;

case IDS_SERVER: /* Listen */

CheckDlgButton(hDlg, IDS_CLIENT, 0);

CheckDlgButton(hDlg, IDS_SERVER, 1);

break;

default:

break;

}

return;

}


/* 以下就是我们如何处理“模拟阻塞”-本函数检查消息队列,如果发现需要处理的消息,就返回一个正的值。*/

int

ShoutBlockingHook (void)

{

MSG msg; /* lets us pull messages via PeekMessage */

int ret = PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE);


if (ret) {

TranslateMessage(&amp;msg);

DispatchMessage(&amp;msg);

}

return ret;

}


char *

_calloc (nelem, elsize)

unsigned nelem, elsize;

{

HANDLE hMem;

PSTR ptr;

unsigned size = nelem * elsize;


if ((hMem = LocalAlloc(LPTR, size)) == NULL)

return (char *) 0;

if ((ptr = LocalLock(hMem)) == NULL) {

LocalFree(hMem);

return (char *) 0;

}

return (char *) ptr;

}


void

_free (void *cP)

{

(void) LocalFree(LocalHandle((WORD) cP));

}


void

ClearBoxes(HWND hOurDlg)

{

wsprintf(prbuf," /n");

SetDlgItemText(hOurDlg, IDD_WRITE, (LPSTR) prbuf);

SetDlgItemText(hOurDlg, IDD_SENT, (LPSTR) prbuf);

SetDlgItemText(hOurDlg, IDD_TIME, (LPSTR) prbuf);

SetDlgItemText(hOurDlg, IDD_WRITES,(LPSTR) prbuf);

SetDlgItemText(hOurDlg, IDD_BYTES, (LPSTR) prbuf);

SetDlgItemText(hOurDlg, IDD_BITS, (LPSTR) prbuf);


return;

}


/*

* wshout_err()函数

* 描述:

*

* 通过错误代码获取相应的错误描述文本,与用户提供的错误前缀合

* 并,并显示在对话框中。

*/

void wshout_err (HWND hOurDlg, /* 对话框的窗口句柄 */

int wsa_err, /* WinSock错误代码 */

char far *err_prefix) /* 错误前缀字符串 */

{

char errbuf[PRBUF_LEN]; /* 错误描述字符串缓冲区 */


/* 获取错误描述字符串 */

WSAsperror(hInst, wsa_err, (LPSTR)errbuf, PRBUF_LEN);


/* 合并错误描述字符串与用户错误前缀字符串 */

wsprintf((LPSTR)prbuf, "%s:%s", (LPSTR) err_prefix, (LPSTR)errbuf);


/* 在对话框中显示错误文本 */

SetDlgItemText(hOurDlg, IDD_COMMENT, (LPSTR) prbuf);


} /* end wshout_err() */


 

/* eof */

 

3.4.3.2 wshout.h清单

/*

* 文件名: WSHOUT.H

*/


#ifndef _WSHOUT_INC_

#define _WSHOUT_INC_


/* Windows 3.0 头文件 */

#include <windows.h>

#define _INC_WINDOWS

#include <winsock.h>


#ifdef __cplusplus

extern "C" {

#endif /* __cplusplus */


 

/* WSHOUT.C 中定义的全局变量 */

extern HANDLE hInst; /* Instance handle */

extern HWND hOurWnd; /* Main Window Handle */

extern int ret; /* work variable */


#define PRBUF_LEN 50

extern char prbuf[PRBUF_LEN]; /* work buffer */


/* 菜单IDs */

#define IDM_START 101

#define IDM_ABOUT 102

#define IDM_STOP 103

#define IDM_EXIT 104

#define IDM_SETTINGS 105


/* 对话框控制IDs */

#define IDD_HNAME 200

#define IDD_CONNECT IDOK

#define IDD_CANCEL IDCANCEL

#define IDD_WRITES 208

#define IDD_BYTES 210

#define IDD_BITS 212

#define IDD_HELP 214

#define IDD_SENT 230

#define IDD_WRITE 232

#define IDD_TIME 234

#define IDD_COMMENT 236

#define IDD_COHOST 240


/* “Settings”对话框控制IDs */

#define IDS_BUFFLEN 300

#define IDS_PORTNO 301

#define IDS_BLOCK 302

#define IDS_NOBLOCK 304

#define IDS_TCP 306

#define IDS_UDP 308

#define IDS_CLIENT 310

#define IDS_SERVER 312

#define IDS_DEFAULT 314


/* “About”对话框控制IDs */

#define IDA_COPYRIGHT 400

#define IDA_APP_VERSION 402

#define IDA_DLL_VERSION 404


/* 程序控制IDs */

#define WM_SELECT WM_USER+16


/* 全局变量*/

#define SOCK_DISCARD 9 /* use the UDP ttytst source port for test */

#define SOCK_SHOUT 32766 /* TCP port used for SHOUT &amp; LISTEN */

#define BUF_SIZE 8192

#define WRITE_TIMER 1


/* 函数原型 */

int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);

long FAR PASCAL ShoutWndProc(HWND, WORD, WORD, LONG);

BOOL FAR PASCAL About(HWND, WORD, WORD, LONG);

BOOL FAR PASCAL DialogProc(HWND, WORD, WORD, LONG);

BOOL FAR PASCAL Settings(HWND, WORD, WORD, LONG);

BOOL InitApp(HANDLE);

void CheckThisBoxOn(HWND, int);

void CheckThisProtoBoxOn(HWND, int);

void CheckThisProgBoxOn(HWND, int);

void ClearBoxes(HWND);

SOCKET ResolveAndConnectHost(LPSTR, HWND, int, int);

SOCKET GetSocketAndBind(HWND, int, int);

long UWriteData(SOCKET, HWND, int);

long UReadData(SOCKET, HWND, int);

long TWriteData(SOCKET, HWND, int);

long TReadData(SOCKET, HWND, int);

int ShoutBlockingHook (void);

int PASCAL FAR WSAsperror (HANDLE, int, char far *, int);

void wshout_err (HWND, int, char far *);


#define bcopy(a,b,c) _fmemcpy(b,a,c)

char * _calloc (unsigned, unsigned);

void _free (void *);


#ifdef _cplusplus

}

#endif /* __cplusplus */


#endif /* ifndef _WSHOUT_INC_ */


/* eof */

 

3.4.3.3 wshout.rc清单

/*

* 文件名: WSHOUT.RC

*/

#include <windows.h>

#include <winsock.h>

#include "wshout.h"


MainMenu MENU

BEGIN

POPUP "&amp;File"

BEGIN

MENUITEM "&amp;Start", IDM_START

MENUITEM "Sto&amp;p", IDM_STOP

MENUITEM SEPARATOR

MENUITEM "E&amp;xit", IDM_EXIT

END


POPUP "&amp;Options"

BEGIN

MENUITEM "&amp;Settings ...", IDM_SETTINGS

MENUITEM SEPARATOR

MENUITEM "&amp;About Shout...", IDM_ABOUT

END


END


ABOUTBOX DIALOG 22, 17, 144, 102

CAPTION "About Shout for Windows"

STYLE DS_MODALFRAME | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU

BEGIN

CTEXT "Windows Shout", -1, 29, 5, 85, 8

CTEXT "Version", -1, 46, 13, 33, 8, SS_CENTER | WS_GROUP

CTEXT "WINSOCK.DLL /n FTP Software, Inc. /nCopyright 1993", IDA_COPYRIGHT, 38, 40, 68, 25, SS_CENTER | WS_GROUP

CTEXT "Version", -1, 46, 67, 33, 8, SS_CENTER | WS_GROUP

CTEXT "num", IDA_DLL_VERSION, 79, 67, 18, 8, SS_CENTER | WS_GROUP

CONTROL "OK", 1, "BUTTON", BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP, 56, 82, 32, 14

ICON "SHOUT", -1, 11, 8, 16, 16

CONTROL "num", IDA_APP_VERSION, "STATIC", SS_LEFT | WS_GROUP, 79, 13, 18, 8

CONTROL "using", -1, "STATIC", SS_CENTER | WS_GROUP, 55, 26, 30, 8

END


SettingsDialog DIALOG 9, 16, 172, 117

CAPTION "Settings"

STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

BEGIN

CONTROL " send/recv /nBuffer &amp;length", -1, "STATIC", SS_LEFT | WS_GROUP, 84, 8, 48, 20

CONTROL "&amp;Port number", -1, "STATIC", SS_LEFT | WS_GROUP, 84, 31, 48, 10

CONTROL "&amp;Blocking", IDS_BLOCK, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 100, 61, 56, 12

CONTROL "&amp;TCP", IDS_TCP, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 20, 60, 41, 12

CONTROL "&amp;Client", IDS_CLIENT, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 19, 15, 35, 12

CONTROL "&amp;Server", IDS_SERVER, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 19, 26, 35, 12

CONTROL "&amp;UDP", IDS_UDP, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 20, 72, 41, 12

CONTROL "&amp;Nonblocking", IDS_NOBLOCK, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 100, 73, 56, 12

CONTROL "O.K.", IDOK, "BUTTON", BS_PUSHBUTTON | WS_TABSTOP, 40, 95, 37, 14

CONTROL "Cancel", IDCANCEL, "BUTTON", BS_PUSHBUTTON | WS_TABSTOP, 90, 95, 37, 14

CONTROL "", IDS_BUFFLEN, "EDIT", ES_CENTER | WS_BORDER | WS_TABSTOP, 130, 11, 36, 12

CONTROL "", IDS_PORTNO, "EDIT", ES_CENTER | WS_BORDER | WS_TABSTOP, 130, 29, 36, 12

CONTROL "Protocol", 237, "button", BS_GROUPBOX, 6, 49, 70, 38

CONTROL "I/O Mode", 239, "button", BS_GROUPBOX, 90, 49, 70, 38

CONTROL "Program Mode", 241, "button", BS_GROUPBOX, 6, 7, 70, 34

END


MainDialog DIALOG 17, 32, 163, 135

CAPTION "Windows Shout"

MENU MainMenu

STYLE DS_ABSALIGN | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX

BEGIN

CONTROL "", IDD_HNAME, "EDIT", ES_CENTER | WS_BORDER | WS_GROUP | WS_TABSTOP, 62, 9, 93, 12

CONTROL "", IDD_WRITE, "STATIC", SS_CENTER | SS_NOPREFIX | WS_BORDER, 7, 95, 45, 11

CONTROL "", IDD_SENT, "STATIC", SS_CENTER | WS_BORDER, 59, 95, 45, 11

CONTROL "", IDD_TIME, "STATIC", SS_CENTER | WS_BORDER, 111, 95, 45, 11

CONTROL "", IDD_WRITES, "STATIC", SS_CENTER | WS_BORDER, 7, 120, 45, 11

CONTROL "", IDD_BYTES, "STATIC", SS_CENTER | WS_BORDER, 59, 120, 45, 11

CONTROL "", IDD_BITS, "STATIC", SS_CENTER | WS_BORDER, 111, 120, 45, 11

CONTROL "writes[reads]", 105, "STATIC", SS_CENTER | WS_GROUP, 3, 85, 52, 9

CONTROL "writes[reads]/s", 105, "STATIC", SS_CENTER | WS_GROUP, 3, 111, 55, 9

CONTROL "bytes", 105, "STATIC", SS_CENTER | WS_GROUP, 61, 85, 42, 9

CONTROL "bytes/sec", 105, "STATIC", SS_CENTER | WS_GROUP, 61, 111, 42, 9

CONTROL "time (sec)", 105, "STATIC", SS_CENTER | WS_GROUP, 111, 85, 45, 9

CONTROL "bits/sec", 105, "STATIC", SS_CENTER | WS_GROUP, 113, 111, 42, 9

CONTROL "Host", IDD_COHOST, "STATIC", SS_LEFT, 7, 10, 52, 10

CONTROL "", IDD_COMMENT, "STATIC", SS_CENTER | WS_BORDER | WS_GROUP, 9, 68, 146, 11

CONTROL "&amp;Start", IDOK, "BUTTON", BS_PUSHBUTTON | WS_TABSTOP, 6, 32, 32, 20

CONTROL "Sto&amp;p", IDCANCEL, "BUTTON", BS_PUSHBUTTON | WS_TABSTOP, 65, 32, 32, 20

CONTROL "E&amp;xit", IDM_EXIT, "BUTTON", BS_PUSHBUTTON | WS_TABSTOP, 125, 32, 32, 20

CONTROL "", -1, "static", SS_BLACKFRAME, 0, 60, 163, 1

END


SHOUT ICON wshout.ico


 

/*

* 错误描述字符串表

* 用于WSAsperror()函数

*/

STRINGTABLE

BEGIN

WSABASEERR, "[0] No Error"

WSAEINTR, "[10004] Interrupted system call"

WSAEBADF, "[10009] Bad file number"

WSAEACCES, "[10013] Permission denied"

WSAEFAULT, "[10014] Bad address"

WSAEINVAL, "[10022] Invalid argument"

WSAEMFILE, "[10024] Too many open files"

WSAEWOULDBLOCK, "[10035] Operation would block"

WSAEINPROGRESS, "[10036] Operation now in progress"

WSAEALREADY, "[10037] Operation already in progress"

WSAENOTSOCK, "[10038] Socket operation on non-socket"

WSAEDESTADDRREQ, "[10039] Destination address required"

WSAEMSGSIZE, "[10040] Message too long"

WSAEPROTOTYPE, "[10041] Protocol wrong type for socket"

WSAENOPROTOOPT, "[10042] Bad protocol option"

WSAEPROTONOSUPPORT, "[10043] Protocol not supported"

WSAESOCKTNOSUPPORT, "[10044] Socket type not supported"

WSAEOPNOTSUPP, "[10045] Operation not supported on socket"

WSAEPFNOSUPPORT, "[10046] Protocol family not supported"

WSAEAFNOSUPPORT, "[10047] Address family not supported by protocol family"

WSAEADDRINUSE, "[10048] Address already in use"

WSAEADDRNOTAVAIL, "[10049] Can't assign requested address"

WSAENETDOWN, "[10050] Network is down"

WSAENETUNREACH, "[10051] Network is unreachable"

WSAENETRESET, "[10052] Net dropped connection or reset"

WSAECONNABORTED, "[10053] Software caused connection abort"

WSAECONNRESET, "[10054] Connection reset by peer"

WSAENOBUFS, "[10055] No buffer space available"

WSAEISCONN, "[10056] Socket is already connected"

WSAENOTCONN, "[10057] Socket is not connected"

WSAESHUTDOWN, "[10058] Can't send after socket shutdown"

WSAETOOMANYREFS, "[10059] Too many references, can't splice"

WSAETIMEDOUT, "[10060] Connection timed out"

WSAECONNREFUSED, "[10061] Connection refused"

WSAELOOP, "[10062] Too many levels of symbolic links"

WSAENAMETOOLONG, "[10063] File name too long"

WSAEHOSTDOWN, "[10064] Host is down"

WSAEHOSTUNREACH, "[10065] No Route to Host"

WSAENOTEMPTY, "[10066] Directory not empty"

WSAEPROCLIM, "[10067] Too many processes"

WSAEUSERS, "[10068] Too many users"

WSAEDQUOT, "[10069] Disc Quota Exceeded"

WSAESTALE, "[10070] Stale NFS file handle"

WSAEREMOTE, "[10071] Too many levels of remote in path"

WSASYSNOTREADY, "[10091] Network SubSystem is unavailable"

WSAVERNOTSUPPORTED, "[10092] WINSOCK DLL Version out of range"

WSANOTINITIALISED, "[10093] Successful WSASTARTUP not yet performed"

WSAHOST_NOT_FOUND, "[11001] Host not found"

WSATRY_AGAIN, "[11002] Non-Authoritative Host not found"

WSANO_RECOVERY, "[11003] Non-Recoverable errors: FORMERR, REFUSED, NOTIMP"

WSANO_DATA, "[11004] Valid name, no data record of requested

type"

END


/* eof */

 

3.4.3.4 ushout.c清单

/*

* 文件名: USHOUT.C

*/


#include "wshout.h"


/* MSC Include files: */

#include <stdio.h>

#include <io.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>


/* Returns the number of bytes written */

long UWriteData(SOCKET hSock, HWND hOurDlg, int send_len)

{

int counter;

static int DataBuffer[BUF_SIZE]; /* Buffer to hold generated data */

static char ReplyBuffer[512]; /* Buffer to hold any reply rcvd */

long bytes_sent = 0L; /* Counter of bytes on connection */

long total_len = 1024L*1024L; /* Total # of bytes to generate */

time_t start, end; /* variables to hold read timing */

long total_time = 0L; /* variable to hold delta t */

long write_count = 0L; /* number of times */

long tmp = 0L; /* holds count for bytes written */

long ltemp = 0L;

int i_temp;

extern int run_cancelled;


struct sockaddr_in dest; /* Destination machine address structure */


/* What makes shout unique is that it generates data*

* in memory (as opposed to accessing the disk). *

* This tests the 'raw' speed of the TCP connection *

* as the rate-limiting access time is eliminated. *

* First, generate the data and place it into an *

* array, data_buffer: */


for (counter = 0; counter < BUF_SIZE; counter++)

DataBuffer[counter] = counter;


/* Write data on the descriptor like a banshee,

* careful to time the writes and count data

* transmitted:

*/


SetDlgItemText(hOurDlg, IDD_COMMENT, "Sending UDP Data ...");

time( &amp;start );

while (bytes_sent < total_len){/* while still bytes to send */

do {

;

} while (ShoutBlockingHook()); /* Dispatch messages if any */


if (run_cancelled) {

WSASetLastError(WSAEINTR);

break; /* Non-blocking mode was cancelled */

}


tmp = send(hSock, (char FAR *) &amp;DataBuffer, send_len, 0);

if (tmp == SOCKET_ERROR) {

if (h_errno == WSAEWOULDBLOCK) /* if no data, read again */

continue;

else {

wshout_err (hOurDlg, WSAGetLastError(), "send()");

}


/* Calc. time elapsed &amp; stats about any data sent */

time(&amp;end);

if (total_time = (long) difftime(end, start)) {

/* Print the statistics gathered */

wsprintf((LPSTR)prbuf,"%ld/n",write_count);

SetDlgItemText(hOurDlg, IDD_WRITE, (LPSTR) prbuf);


wsprintf((LPSTR)prbuf,"%ld/n",bytes_sent);

SetDlgItemText(hOurDlg, IDD_SENT, (LPSTR) prbuf);


wsprintf((LPSTR)prbuf,"%ld/n",total_time);

SetDlgItemText(hOurDlg, IDD_TIME, (LPSTR) prbuf);


ltemp = write_count/total_time;

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_WRITES,(LPSTR) prbuf);


ltemp = bytes_sent/total_time;

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_BYTES, (LPSTR) prbuf);


ltemp = 8 * (bytes_sent/total_time);

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_BITS, (LPSTR) prbuf);


/* exit from the while loop */

break;

} /* end if (total_time) */

write_count++; /* incr. counter of times written */

bytes_sent += tmp; /* # of bytes placed on connection */

wsprintf((LPSTR)prbuf,"%ld/n",bytes_sent);

SetDlgItemText(hOurDlg, IDD_SENT, (LPSTR) prbuf);

} /* end if (tmp == -1) */


write_count++; /* incr. counter of times written */

bytes_sent += tmp; /* # of bytes placed on connection */

wsprintf((LPSTR)prbuf,"%ld/n",write_count);

SetDlgItemText(hOurDlg, IDD_WRITE, (LPSTR) prbuf);


wsprintf((LPSTR)prbuf,"%ld/n",bytes_sent);

SetDlgItemText(hOurDlg, IDD_SENT, (LPSTR) prbuf);

} /* end while */


/* Look for a reply ... NOTE: most hosts won't give

* a 'reply', done to illustrate communication between

* sockets. Our ulisten example will give a reply though.

*/


SetDlgItemText(hOurDlg, IDD_COMMENT, "Waiting for reply from server../n");

while (1) {

tmp = sizeof(dest);

i_temp = recvfrom(hSock,(char FAR *) &amp;ReplyBuffer,sizeof(ReplyBuffer),

0, (struct sockaddr *) &amp;dest, (int FAR *) &amp;tmp);

if (i_temp == SOCKET_ERROR) {

if (h_errno == WSAEWOULDBLOCK) /* if no data, read again */

continue;

else {

/* any error besides these. just punt */

wshout_err (hOurDlg, WSAGetLastError(), "recvfrom()");

}

break;

} /* end if (i_temp == SOCKET_ERROR) */

/* else got a reply ...*/

wsprintf((LPSTR)prbuf, "Server: %s/n", (LPSTR) ReplyBuffer);

SetDlgItemText(hOurDlg, IDD_COMMENT, prbuf);

break;

} /* end while(1) */


/* All done */

return bytes_sent;

}


/* eof */

 

3.4.3.5 ulisten.c清单

/*

* 文件名: ULISTEN.C

*/


#include "wshout.h"


 

/* MSC Include files: */

#include <stdio.h>

#include <io.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>


/* Returns the number of bytes written */

long UReadData(SOCKET hSock, HWND hOurDlg, int read_len)

{

static char ReadBuf[BUF_SIZE];

static char SendBuf[512];

struct sockaddr_in local; /* Local machine address structure */

int i; /* General purpose return code */

long total_time = 0L; /* variable to hold delta t */

int tmp, len = 0;

int num_reads = 0;

long bytes_read = 0L;

long last_time, now, timeout = 15L;

long ltemp;

extern int run_cancelled;


BOOL bTemp = TRUE;


SetDlgItemText(hOurDlg, IDD_COMMENT, "Awaiting the UDP Data ...");

SetDlgItemText(hOurDlg, IDD_HNAME, " ");


time(&amp;now); time(&amp;last_time);

while (last_time + timeout > now) {

time(&amp;now);

tmp = sizeof(local);

do {

;

} while (ShoutBlockingHook()); /* Dispatch messages while available */


if (run_cancelled) {

WSASetLastError(WSAEINTR);

break; /* Non-blocking mode was cancelled */

}


len = recvfrom(hSock, ReadBuf, read_len, 0,

(struct sockaddr *) &amp;local, &amp;tmp);

if (len == SOCKET_ERROR) {

if (h_errno == WSAEWOULDBLOCK) {/* if no data, read again */

continue;

} /* end: if (errno == WSAEWOULDBLOCK) */

else {

if (bytes_read) {

wshout_err (hOurDlg, WSAGetLastError(), "recvfrom()");

}

} /* end else */

break;

} /* end: if (len == SOCKET_ERROR) */


if (bTemp) { /* To update our main display once */

/* Do not use wsprintf() or you will add an extra char */

_fmemcpy(prbuf, inet_ntoa(local.sin_addr), 4*sizeof(u_long));

SetDlgItemText(hOurDlg, IDD_HNAME, (LPSTR) prbuf);

SetDlgItemText(hOurDlg, IDD_COMMENT, "Reading UDP Data ...");

bTemp = FALSE;

}


num_reads++;

if (len != SOCKET_ERROR)

bytes_read += len;

/* Print the statistics gathered */

wsprintf((LPSTR)prbuf,"%d/n",num_reads);

SetDlgItemText(hOurDlg, IDD_WRITE, (LPSTR) prbuf);


wsprintf((LPSTR)prbuf,"%ld/n",bytes_read);

SetDlgItemText(hOurDlg, IDD_SENT, (LPSTR) prbuf);


time(&amp;last_time);

} /* end: while */

total_time = timeout;


wsprintf((LPSTR)prbuf,"%ld/n",total_time);

SetDlgItemText(hOurDlg, IDD_TIME, (LPSTR) prbuf);


ltemp = num_reads/total_time;

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_WRITES,(LPSTR) prbuf);


ltemp = bytes_read/total_time;

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_BYTES, (LPSTR) prbuf);


ltemp = 8 * (bytes_read/total_time);

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_BITS, (LPSTR) prbuf);


if (bytes_read) {

SetDlgItemText(hOurDlg, IDD_COMMENT, "...UDP Listen Done/n");

} /* end: if (bytes_read) */

else {

wsprintf((LPSTR)prbuf, "Timed out. No data received./n");

SetDlgItemText(hOurDlg, IDD_COMMENT, prbuf);

goto come_here;

} /* end: else */


/* send reply to 'client' */

wsprintf((LPSTR)prbuf,

"Replied to %s/n", inet_ntoa(local.sin_addr));

SetDlgItemText(hOurDlg, IDD_COMMENT, prbuf);


for (i=0; i<10; ++i) {

sprintf(SendBuf, "Rec'd %ld bytes./n", bytes_read);

if(len = sendto(hSock, SendBuf, sizeof(SendBuf), 0,

(struct sockaddr FAR *)&amp;local,sizeof(local)))

{

if (len == SOCKET_ERROR) { /* if could not send bec. */

if (h_errno == WSAEWOULDBLOCK)

continue;

wshout_err (hOurDlg, WSAGetLastError(), "sendto()");

break;

} /* end: if (len == -1) */

} /* end: if (len = sendto()) */

} /* end for */

come_here:

return (bytes_read);

}


/* eof */

 

3.4.3.6 tshout.c清单

/*

* 文件名: TSHOUT.C

*/


#include "wshout.h"


/* MSC Include files: */

#include <stdio.h>

#include <io.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>


 

/* Returns the number of bytes written */

long TWriteData(SOCKET hSock, HWND hOurDlg, int send_len)

{

int counter;

static int DataBuffer[BUF_SIZE]; /* Buffer to hold generated data */

long total_len = 1024L*1024L; /* Total # of bytes to generate */

long bytes_sent = 0L; /* Counter of bytes on connection */

int tmp = 0; /* holds count for bytes written */

long write_count = 0L; /* number of times */

time_t start, end; /* variables to hold read timing */

long total_time = 0L; /* variable to hold delta t */

long ltemp = 0L;

extern int run_cancelled;


/* What makes shout unique is that it generates data*

* in memory (as opposed to accessing the disk). *

* This tests the 'raw' speed of the TCP connection *

* as the rate-limiting access time is eliminated. *

* First, generate the data and place it into an *

* array, data_buffer: */


for (counter = 0; counter < BUF_SIZE; counter++)

DataBuffer[counter] = counter;


/* Write data on the descriptor like a banshee,

* careful to time the writes and count data

* transmitted:

*/


SetDlgItemText(hOurDlg, IDD_COMMENT, "...Sending TCP Data");

time(&amp;start);

while ( bytes_sent < total_len) { /* while still bytes to send... */

do {

;

} while (ShoutBlockingHook()); /* Dispatch messages if any */


if (run_cancelled) {

WSASetLastError(WSAEINTR);

break; /* Non-blocking mode was cancelled */

}


tmp = send(hSock, (char FAR*) &amp;DataBuffer, send_len, 0);

if (tmp == SOCKET_ERROR) {

if (h_errno == WSAEWOULDBLOCK)

continue;

else {

wshout_err (hOurDlg, WSAGetLastError(), "send()");

}


/* Calc. time elapsed &amp; stats about any data sent */

time(&amp;end);

/* exit from the while loop */

break;


} /* end if (tmp == -1) */

write_count++; /* incr. counter of times written */

bytes_sent += tmp; /* total # of bytes placed on connection*/

wsprintf(prbuf,"%ld/n",write_count);

SetDlgItemText(hOurDlg, IDD_WRITE, (LPSTR) prbuf);


wsprintf(prbuf,"%ld/n",bytes_sent);

SetDlgItemText(hOurDlg, IDD_SENT, (LPSTR) prbuf);

} /* end while */

time(&amp;end);


if (total_time = (long) difftime(end, start)) {

/* Print the statistics gathered */

wsprintf((LPSTR)prbuf,"%ld/n",total_time);

SetDlgItemText(hOurDlg, IDD_TIME, (LPSTR) prbuf);


ltemp = write_count/total_time;

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_WRITES,(LPSTR) prbuf);


ltemp = bytes_sent/total_time;

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_BYTES, (LPSTR) prbuf);


ltemp = 8 * (bytes_sent/total_time);

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_BITS, (LPSTR) prbuf);

} /* end if (total_time) */


/* All done */

SetDlgItemText(hOurDlg, IDD_COMMENT, "...TCP Shout Done");

return bytes_sent;

}


/* eof */

 

3.4.3.7 tlisten.c清单

/*

* 文件名:TLISTEN.C

*/


#include "wshout.h"


/* MSC Include files: */

#include <stdio.h>

#include <io.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>


 

/* Returns the number of bytes written */

long TReadData(SOCKET hSock, HWND hOurDlg, int read_len)

{

static char ReadBuf[BUF_SIZE];

SOCKET hAcceptSock;

struct sockaddr_in local; /* Local machine address structure */

long total_time = 0L; /* variable to hold delta t */

int tmp, len = 0;

int num_reads = 0;

long bytes_read = 0L;

long last_time = 0L;

long now = 0L;

long ltemp;

extern long blocking_option;

extern int run_cancelled;

struct linger AcceptLinger;


BOOL running = FALSE;

BOOL bTemp = TRUE;


SetDlgItemText(hOurDlg, IDD_COMMENT, "Awaiting the TCP Data ...");

SetDlgItemText(hOurDlg, IDD_HNAME, " ");


tmp = sizeof(local);

if (!blocking_option) {

hAcceptSock = accept(hSock,(struct sockaddr FAR *)&amp;local,

(int FAR *)&amp;tmp);

}

else {

for (;;) {

do {

;

} while (ShoutBlockingHook()); /* Dispatch messages if any */


if (run_cancelled) {

WSASetLastError(WSAEINTR);

break; /* Non-blocking mode was cancelled */

}


hAcceptSock = accept(hSock,(struct sockaddr FAR *)&amp;local,

(int FAR *)&amp;tmp);

if (hAcceptSock == INVALID_SOCKET) {

if (h_errno == WSAEWOULDBLOCK)

/* Try again */

;

else {

/* Fatal error -- pop out. */

break;

}

} /* end if ((hAcceptSock = .. */

else {

/* Success -- pop out. */

break;

}

} /* end for */

} /* end else */


if (hAcceptSock == INVALID_SOCKET) {

wshout_err (hOurDlg, WSAGetLastError(), "accept()");

return 0;

}


/* Now, read the data as fast as we can until no more to read */

time(&amp;last_time);

do {

do {

;

} while (ShoutBlockingHook()); /* Dispatch messages while available */


if (run_cancelled) {

WSASetLastError(WSAEINTR);

break; /* Non-blocking mode was cancelled */

}


len = recv(hAcceptSock, ReadBuf, read_len, 0);

if (len == SOCKET_ERROR) {

if (h_errno == WSAEWOULDBLOCK)

continue;

else

break;

}

else if (len == 0)

break;

num_reads++;

bytes_read += len;


wsprintf((LPSTR)prbuf,"%d/n",num_reads);

SetDlgItemText(hOurDlg, IDD_WRITE, (LPSTR) prbuf);


wsprintf((LPSTR)prbuf,"%ld/n",bytes_read);

SetDlgItemText(hOurDlg, IDD_SENT, (LPSTR) prbuf);


if (bTemp) { /* To update our main display once */

/* Do not use wsprintf() or you will add an extra char */

_fmemcpy(prbuf, inet_ntoa(local.sin_addr), 4*sizeof(u_long));

SetDlgItemText(hOurDlg, IDD_HNAME, (LPSTR) prbuf);

SetDlgItemText(hOurDlg, IDD_COMMENT, "Reading TCP Data ...");

bTemp = FALSE;

}


} while ((len != 0) || (len != SOCKET_ERROR));

time (&amp;now);


if (len == SOCKET_ERROR) {

if ((h_errno == WSAESHUTDOWN) || (h_errno == WSAENOTCONN)) {

/* nothing available for read. */

wsprintf((LPSTR)prbuf,

"Connection from %s closed./n",inet_ntoa(local.sin_addr));

SetDlgItemText(hOurDlg, IDD_COMMENT, prbuf);

}

else { /* Other error */

wshout_err (hOurDlg, WSAGetLastError(), "recv()");

}

}

else if (len == 0) {

/* Other side shut down the connection */

wsprintf((LPSTR)prbuf,

"Connection from %s closed./n",inet_ntoa(local.sin_addr));

SetDlgItemText(hOurDlg, IDD_COMMENT, prbuf);

}


AcceptLinger.l_onoff = 1;

AcceptLinger.l_linger = 0;

ret = setsockopt(hAcceptSock, SOL_SOCKET, SO_LINGER,

(char FAR *) &amp;AcceptLinger, sizeof(AcceptLinger));

if (ret == SOCKET_ERROR) {

wshout_err (hOurDlg, WSAGetLastError(), "setsockopt()");

}


ret = closesocket(hAcceptSock);

if (ret == SOCKET_ERROR) {

wshout_err (hOurDlg, WSAGetLastError(), "closesocket()");

}


total_time = (long) difftime(now, last_time);

if (total_time == 0)

total_time = 1L; /* Avoid dividing by zero */


wsprintf((LPSTR)prbuf,"%ld/n",total_time);

SetDlgItemText(hOurDlg, IDD_TIME, (LPSTR) prbuf);


ltemp = num_reads/total_time;

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_WRITES,(LPSTR) prbuf);


ltemp = bytes_read/total_time;

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_BYTES, (LPSTR) prbuf);


ltemp = 8 * (bytes_read/total_time);

wsprintf((LPSTR)prbuf,"%ld/n", ltemp);

SetDlgItemText(hOurDlg, IDD_BITS, (LPSTR) prbuf);


if (bytes_read) {

SetDlgItemText(hOurDlg, IDD_COMMENT, "...TCP Listen Done/n");

} /* end: if (bytes_read) */


return (bytes_read);

}


/* eof */

 

3.4.3.8 errno.c清单

#include <windows.h>

#include <winsock.h>


/*

* 文件名: ERRNO.C

*/


/*

* Function: WSAsperror()

*

* Description:

*

* Copies string corresponding to the error code provided

* into buf, maximum length len. Returns length actually

* copied to buffer, or zero if error code is unknown.

* String resources should be present for each error code

* using the value of the code as the string ID (except for

* error = 0, which is mapped to WSABASEERR to keep it with

* the others). The DLL is free to use any string IDs that

* are less than WSABASEERR for its own use.

*

*/

int PASCAL FAR WSAsperror (HANDLE hInst, /* Instance Handle */

int errorcode, /* WSA Error Number */

char far * buf, /* Buffer for error string */

int len) /* Length of buffer */

{

int err_len; /* length of error text */


if (errorcode == 0) /* If error passed is 0, use the */

errorcode = WSABASEERR; /* base resource file number */

if (errorcode < WSABASEERR) /* If invalid Error code */

return 0; /* return string length of zero */


/* error string from the table in the Resource file into buffer */

err_len = LoadString(hInst,errorcode,buf,len);


return (err_len); /* return length of error string retrieved */


} /* end WSAsperror() */


/* eof */

 

3.4.3.9 resolve.c清单

/*

* 文件名: RESOLVE.C

*/


#include "wshout.h"


/* MSC Include files: */

#include <stdio.h>

#include <io.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>


 

SOCKET

ResolveAndConnectHost(LPSTR lpHostName,HWND hOurDlg,int iproto, int iSockPort)

{

struct hostent FAR *host_ptr; /* Ptr to the host name */

struct sockaddr_in dest; /* Addr of target host */

SOCKET hSock; /* The socket to create */

int iSockType;

extern int iTCP;

extern int iUDP;


/* Internet family addressing */

dest.sin_family = PF_INET;

if (iproto == iTCP) {

iSockType = SOCK_STREAM;

}

else if (iproto == iUDP) {

iSockType = SOCK_DGRAM;

}

else {

return (SOCKET) -1; /* Unknown protocol */

}


/* default port to connect to. Must be in network byte order */

dest.sin_port = htons((u_int) iSockPort);


SetDlgItemText(hOurDlg, IDD_COMMENT,"Resolving hostname...");


/* Resolve the host name */

host_ptr = gethostbyname(lpHostName);

if (host_ptr == NULL) {

wshout_err (hOurDlg, WSAGetLastError(), "gethostbyname()");

return (SOCKET) -1;

}

/* Patch host address into struct describing conn: */

bcopy(host_ptr->h_addr,&amp;dest.sin_addr,host_ptr->h_length);


/* Allocate a network (socket) descriptor: */

hSock = socket(PF_INET, iSockType, 0);

if (hSock == INVALID_SOCKET) {

wshout_err (hOurDlg, WSAGetLastError(), "socket()");

return (SOCKET) -1;

}


/* Start connection process to host described in 'dest' *

* struct.

*/

SetDlgItemText(hOurDlg, IDD_COMMENT, "Connecting ...");

ret=connect(hSock,(struct sockaddr FAR *)&amp;dest,sizeof(dest));


if (ret == SOCKET_ERROR) {

wshout_err (hOurDlg, WSAGetLastError(), "connect()");

closesocket(hSock);

return (SOCKET) -1;

}


SetDlgItemText(hOurDlg, IDD_COMMENT, "...Connected");

return hSock;

}


SOCKET GetSocketAndBind(HWND hOurDlg, int iProto, int iSockPort)

{

SOCKET hSock; /* Connection socket descriptor */

struct sockaddr_in local; /* Local machine address structure*/

int iSockType;

extern int iTCP;

extern int iUDP;


/* Internet family addressing */

if (iProto == iTCP) {

iSockType = SOCK_STREAM;

}

else {

iSockType = SOCK_DGRAM;

}


memset(&amp;local, '/0', sizeof (local));

local.sin_family = PF_INET;

local.sin_port = htons((u_short)iSockPort);


/* allocate a socket descriptor */

hSock = socket(PF_INET, iSockType, 0);

if (hSock == INVALID_SOCKET) { /* socket() failed */

wshout_err (hOurDlg, WSAGetLastError(), "socket()");

return (SOCKET) -1;

}


/* bind socket to a local addr */

ret = bind(hSock, (struct sockaddr FAR *) &amp;local, sizeof(local));

if (ret == SOCKET_ERROR){ /* bind() failed */

wshout_err (hOurDlg, WSAGetLastError(), "bind()");

return (SOCKET) -1;

}


if (iProto == iUDP)

return (hSock);


/* If iProto == iTCP, then must listen() and accept() also */


ret = listen(hSock, 0); /* listen on the socket */

if (ret == SOCKET_ERROR){ /* listen() failed */

wshout_err (hOurDlg, WSAGetLastError(), "listen()");

return (SOCKET) -1;

}


return(hSock);

}


/* eof */
 
张无忌:
WinSock文件传输例程
也给我一份好吗?
fangyuanzhijia@163.com
 
后退
顶部