WEB开发网
开发学院软件开发VC 基于Winsock API的VC网络编程实战 阅读

基于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 Sock

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;
}

四、小结

本实例用它可以发送、接收、连接、断开和获取对方端口各种不同的信息。该类的主要优点是完全将连接对象化,不需要窗口就可以处理网络消息,通过定义回调函数或事件即可,甚至连通知消息都可以不用。如果读者朋友正在开发网络应用程序,那么该类也许会对你有所帮助。

上一页  1 2 3 4 5 6 

Tags:基于 Winsock API

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接