基于Winsock API的VC网络编程实战
2007-03-15 21:52:54 来源:WEB开发网int PASCAL FAR send( SOCKET s, const char FAR *buf,int len, int flags );
参数:s:Socket 的识别码
buf:存放要传送的资料的暂存区
len buf:的长度
flags:此函数被调用的方式
对于Datagram Socket而言,若是 datagram 的大小超过限制,则将不会送出任何资料,并会传回错误值。对Stream Socket 言,Blocking 模式下,若是传送系统内的储存空间不够存放这些要传送的资料,send()将会被block住,直到资料送完为止;如果该Socket被设定为 Non-Blocking 模式,那么将视目前的output buffer空间有多少,就送出多少资料,并不会被 block 住。flags 的值可设为 0 或 MSG_DONTROUTE及 MSG_OOB 的组合。
int PASCAL FAR recv( SOCKET s, char FAR *buf, int len, int flags );
参数:s:Socket 的识别码
buf:存放接收到的资料的暂存区
len buf:的长度
flags:此函数被调用的方式
对Stream Socket 言,我们可以接收到目前input buffer内有效的资料,但其数量不超过len的大小。
本实例在WinSocket API知识的基础上,定义了一个基于网络的类CNetworking ,并利用该类实现了网络通信的基本功能,消息数据的传送,具体请参见代码部分。
二、编程步骤
1、 启动Visual C++6.0,生成一个Win32 exe应用程序,将该程序命名为"CNetWorking"
2、 定义CNetWorking类,由于篇幅原因,具体实现参见代码部分,这里不给出其实现源代码;
3、 设计程序的对话框和菜单(参见代码部分);
4、 添加代码,编译运行程序。
三、程序代码
//////////////////////////////////////////////
#include <windows.h>
#include "resource.h"
#include "CConnection.h"
extern HWND hWndDialog; // used to pass the handle of the dialog the main.cpp
extern CConnection* Connection;
extern CNetworking Networking;
#define CONNECT_PORT 10205
void ReceiveCallback (DWORD ptr);
void CloseCallback (DWORD ptr);
void AcceptCallback (DWORD ptr);
BOOL CALLBACK SendString(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
BOOL CALLBACK SendFile(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
BOOL CALLBACK ConnectToIP(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
//////////////////////////////////////////////////////mian.cpp
#include "main.h"
#define MAX_LOADSTRING 100
HINSTANCE hInst; // current instance
HWND hWnd, hWndDialog; // handle of the dialog
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
CNetworking Networking;
CConnection* Connection = NULL;
int connections[8]; // holds our connection slots...
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void ReceiveCallback (DWORD ptr)
{
char buff[1024] = "";
CConnection* c = reinterpret_cast <CConnection*> (ptr);
c->Receive (buff, 1024);
MessageBox (hWnd, buff, "Information", MB_OK | MB_ICONINFORMATION);
}
void CloseCallback (DWORD ptr)
{
MessageBox (hWnd, "The connection was closed.", "Information", MB_OK | MB_ICONINFORMATION);
}
void AcceptCallback (DWORD ptr)
{
char cip[15];
unsigned int cp = 0;
CNetworking* net = reinterpret_cast <CNetworking*> (ptr);
if (Connection && Connection->IsConnected ())
{
CConnection* c = net->GetAccepted ();
while (c)
{
char nocon[] = "The host can not accept your connection at this time.";
c->Send (nocon, sizeof (nocon));
c->Disconnect ();
delete c;
c = net->GetAccepted ();
};
}
else
{
if (Connection)
delete Connection;
Connection = net->GetAccepted ();
Connection->PeerInfo (&cip[0], 15, &cp);
Connection->SetReceiveFunc (ReceiveCallback);
Connection->SetCloseFunc (CloseCallback);
char ci[128];
sprintf (ci, "A connection was accepted.
Client Information:
%s:%i
", cip, cp);
MessageBox (hWnd, ci, "Client Info", MB_OK | MB_ICONINFORMATION);
}
}
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
{
// TODO: Place code here.
MSG msg;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDS_NETWORKING, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_NETWORKING);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wcex.lpszMenuName = (LPCSTR)IDM_NETWORKING;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_CREATE:
{
hWndDialog = NULL;
SetWindowPos (hWnd, HWND_TOP, 0, 0, 200, 44, SWP_NOOWNERZORDER | SWP_NOMOVE);
char jakobIP[225] = "";
Networking.GetLocalIPs (jakobIP, 225);
MessageBox(NULL, jakobIP, "Info", NULL);
Networking.SetAcceptFunc (AcceptCallback);
break;
}
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow (hWnd);
break;
case IDM_LISTEN:
if (Connection)
{
if (MessageBox (hWnd, "You are still connected to a computer.
Press Yes if you want
to disconnect and No to abort.
Since this is just a demonstration of what you
can
do with Networking I kept things simple.", NULL, MB_YESNO | MB_ICONSTOP) == IDNO)
break;
delete Connection;
Connection = NULL;
}
if (!Networking.Listen (CONNECT_PORT))
{
char cPort[1024] = "";
sprintf (cPort, "Unable to listen at port %i", CONNECT_PORT);
MessageBox (hWnd, cPort, NULL, MB_OK | MB_ICONSTOP);
}
else
{
char cPort[1024] = "";
sprintf (cPort, "Now listening at port %i!
Press 'Ok' to accept
incoming connections.", CONNECT_PORT);
MessageBox (hWnd, cPort, "Listening", MB_OK | MB_ICONINFORMATION);
}
break;
case IDM_CANCELLISTEN:
if (Networking.IsListening ())
Networking.StopListen ();
else
MessageBox (hWnd, "Unable to cancel listen-process!
Make sure you are listening.",
NULL, MB_OK | MB_ICONINFORMATION);
break;
case IDM_CONNECT:
{
if (Connection)
{
Connection->Disconnect ();
}
DialogBox (hInst, "CONNECTIP", hWnd, ConnectToIP);
break;
}
case IDM_SENDMSG:
if (!Connection)
MessageBox(hWnd, "Please connect before sending data.", NULL,
MB_OK | MB_ICONINFORMATION);
else
DialogBox(hInst, "SENDMSG", hWnd, SendString);
break;
case IDM_DISCONNECT:
if (Connection)
Connection->Disconnect ();
else
MessageBox (hWnd, "Unable to close connection!
Make sure you are connected.",
NULL, MB_OK | MB_ICONINFORMATION);
break;
case IDM_LISTLAN:
{
char lanlist[1024] = "";
Networking.GetNeighborhood (lanlist, 1024);
MessageBox (hWnd, lanlist, "Information", MB_OK | MB_ICONINFORMATION);
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
四、小结
本实例用它可以发送、接收、连接、断开和获取对方端口各种不同的信息。该类的主要优点是完全将连接对象化,不需要窗口就可以处理网络消息,通过定义回调函数或事件即可,甚至连通知消息都可以不用。如果读者朋友正在开发网络应用程序,那么该类也许会对你有所帮助。
- ››基于IP地址的vsftp服务器
- ››基于MySQL 水平分区的优化示例
- ››基于CentOS5的Linux下pptp和openvpn的搭建及配置
- ››基于JavaScript的网页版塔防游戏
- ››基于Android平台 QQ大战360手机游戏爆红
- ››基于Windows Azure的云计算应用设计
- ››基于AES算法实现对数据的加密
- ››基于SoPC目标板Flash编程设计的创建及应用
- ››基于SolidWarks齿轮机构的运动分析与仿真
- ››基于Windwos Server 2008故障转移群
- ››基于JavaScript的REST客户端框架
- ››基于JavaScript和CSS的Web图表框架横向对比
更多精彩
赞助商链接