📄 sendit.cpp
字号:
// SendIt.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "SendIt.h"
#include <commctrl.h>
// <BOOK_ADDON Chapter 9.5.1> **************************************
#include <winsock.h>
#define DESIRED_WINSOCK_VERSION 0x0101 // we like winsock ver 1.1...
#define MINIMUM_WINSOCK_VERSION 0x0001 // ...but we'll take ver 1.0
#define MAX_BUF_LEN 1000 // max telegram size
#define PACKET_TYPE_FILE 0x46494c45L // "FILE"
#define PACKET_TYPE_NACK 0x4e41434bL // "NACK"
#define MPPort 4321 // Using Port 4321
#define WM_SOCKET_SELECT (WM_USER + 100) // WSOCK Packet
// received
typedef INT SOCKERR; // A socket error code.
typedef struct _PACKET_FILE // Our Telegram Structure
{
DWORD type; // Must be PACKET_TYPE_FILE.
DWORD cbFile; // Use data size
DWORD PakSize; // Packet size
DWORD Code; // Windows Message for receiver
CHAR szFile[MAX_BUF_LEN]; // The use data
} PACKET_FILE, FAR * LPPACKET_FILE;
SOCKET sCommand = INVALID_SOCKET; // Command socket.
CRITICAL_SECTION m_csec; // Critical Section handle
BOOL MPServerRunning=FALSE; // is TRUE if thread runs
SOCKERR ResetSocket( SOCKET sock )
{
LINGER linger;
if( sock == INVALID_SOCKET )
return 0;
linger.l_onoff = TRUE;
linger.l_linger = 0;
setsockopt( sock,
SOL_SOCKET,
SO_LINGER,
(CHAR FAR *)&linger,
sizeof(linger) );
return closesocket( sock );
} // ResetSocket
SOCKERR CreateSocket( SOCKET FAR * psock,
INT type,
ULONG address,
WORD port )
{
SOCKET sNew;
SOCKERR serr;
sNew = socket( PF_INET, type, 0 );
serr = ( sNew == INVALID_SOCKET ) ? WSAGetLastError() : 0;
if( serr == 0 )
{
SOCKADDR_IN sockAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = address;
sockAddr.sin_port = port;
if( bind( sNew, (SOCKADDR FAR *)&sockAddr,
sizeof(sockAddr) ) != 0 )
{
serr = WSAGetLastError();
}
}
if( serr != 0 )
{
ResetSocket( sNew );
sNew = INVALID_SOCKET;
}
*psock = sNew;
return serr;
} // CreateSocket
DWORD WINAPI SCeThread( LPVOID pParam )
{
INT cbRead; // Bytes read
PACKET_FILE filePacket; // buffer for a datagramm
SOCKADDR_IN addrClient; // The address of the sender
INT cbAddrClient; // Size of the addrClient buffer
BYTE *tBuffer=NULL; // a temporary buffer for the use
// data
int endless; // a loop flag
cbAddrClient = sizeof(addrClient);
endless=TRUE;
while (endless==TRUE)
{
cbRead = recvfrom(sCommand,
(CHAR FAR *)&filePacket,sizeof(filePacket),
0,(SOCKADDR FAR *)&addrClient,&cbAddrClient );
// This command blocks until something comes into the
// WinSock Buffer
if (cbRead<1) // Socket was reset cvRead is zero
{ // we use this to end the thread
endless=FALSE;
if (cbRead==SOCKET_ERROR)
{
cbRead=WSAGetLastError();
if (cbRead==WSAEWOULDBLOCK)
{
endless=TRUE;
continue;
}
}
}
EnterCriticalSection(&m_csec);
// We do not want other thread interrupting us while
// reading the WINSOCK buffer
switch (filePacket.type)
{
case PACKET_TYPE_FILE: // A well know telegram arrived
if (filePacket.cbFile>0)
{
tBuffer = (BYTE *)LocalAlloc(LMEM_ZEROINIT,
filePacket.cbFile);
memcpy(tBuffer,filePacket.szFile,
filePacket.cbFile);
}
PostMessage((HWND)pParam, filePacket.Code,
(WPARAM)tBuffer,
(LPARAM)addrClient.sin_addr.s_addr);
break;
case PACKET_TYPE_NACK:
endless=FALSE;
break;
default:
// Ignore Packet
break;
}
LeaveCriticalSection(&m_csec);
}
return TRUE;
}
BOOL InitServer(HWND hwnd)
{
WSADATA wsadata;
SOCKERR serr;
DWORD ThreadId = 0L;
HANDLE m_pCeThread; // thread handle
if (MPServerRunning) return TRUE;
serr = WSAStartup( DESIRED_WINSOCK_VERSION, &wsadata );
if( serr != 0 ) return FALSE; // More error handling here
if( wsadata.wVersion < MINIMUM_WINSOCK_VERSION ) return FALSE;
serr = CreateSocket( &sCommand, SOCK_DGRAM,
htonl( INADDR_ANY ), htons(MPPort));
if( serr != 0 ) return FALSE; // More error handling here
m_pCeThread = CreateThread( NULL, 0, SCeThread, hwnd,0L,&ThreadId);
//Pass hWnd to Thread
CloseHandle(m_pCeThread);
InitializeCriticalSection(&m_csec);
MPServerRunning=TRUE;
return TRUE;
}
BOOL CloseServer(void)
{
if (MPServerRunning)
{
ResetSocket(sCommand);
WSACleanup();
MPServerRunning=FALSE;
}
return TRUE;
}
SOCKERR SendWSockPacket( SOCKET sock, int len, BYTE *Buffer,
DWORD code, TCHAR *tIP)
{
PACKET_FILE filePacket;
INT cbWritten;
SOCKADDR_IN saUdpServ;
char mpip[20]; // yep, the IP Address has to be ANSI !!
int i;
if (tIP==NULL) return 0;
for (i=0;i<(int)lstrlen(tIP);i++) mpip[i]=(char)tIP[i];
mpip[i]=0; // Converting the tIP Parameter to ANSI
saUdpServ.sin_family = AF_INET; // This is Important !!
// It tells we are using the WINSOCK TCP/IP Layer
saUdpServ.sin_addr.s_addr = inet_addr(mpip);
saUdpServ.sin_port = htons(MPPort); // supplying the Port Number
// Preparing our telegram structure
memset(filePacket.szFile,0,sizeof(filePacket.szFile));
filePacket.type = PACKET_TYPE_FILE; // Packet Type
filePacket.cbFile = len;
filePacket.PakSize= len+(4*sizeof(DWORD));
filePacket.Code = code;
memcpy( filePacket.szFile, Buffer, len);
cbWritten = sendto( sock,
(CHAR FAR *)&filePacket,
filePacket.PakSize, 0,
(SOCKADDR *) &saUdpServ,
sizeof ( SOCKADDR_IN ));
return ( cbWritten == SOCKET_ERROR )
? WSAGetLastError() : 0;
} // SendWSockPacket
BOOL SendPacket(WCHAR *Buffer, DWORD code,TCHAR *tIP)
{
BOOL ret;
long len;
len=(wcslen(Buffer)+1)*sizeof(WCHAR);
// Buffer = String incl. Terminating zero
ret=SendWSockPacket( sCommand, len, (BYTE *)Buffer,code, tIP);
if( ret != 0 ) return FALSE; // more error handling goes here
return TRUE;
}
// </BOOK_ADDON Chapter 9.5.1> **************************************
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // The current instance
HWND hwndCB; // The command bar handle
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass (HINSTANCE hInstance, LPTSTR szWindowClass);
BOOL InitInstance (HINSTANCE, int);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SENDIT);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// <BOOK_ADDON Chapter 9.5.1> **************************************
CloseServer();
// </BOOK_ADDON Chapter 9.5.1> **************************************
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SENDIT));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The window class name
hInst = hInstance; // Store instance handle in our global variable
// Initialize global strings
LoadString(hInstance, IDC_SENDIT, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance, szWindowClass);
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
#ifdef UNDER_CE // <BOOK_ADDON Chapter 9.5.1/> ****
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,
NULL,
hInstance, NULL);
// <BOOK_ADDON Chapter 9.5.1> *****************************
#else
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
0, 0, CW_USEDEFAULT, CW_USEDEFAULT, NULL,
LoadMenu(hInstance,MAKEINTRESOURCE(IDM_MENU)),
hInstance, NULL);
#endif
// <BOOK_ADDON Chapter 9.5.1> *****************************
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
#ifdef UDNER_CE // <BOOK_ADDON Chapter 9.5.1/> ****
if (hwndCB)
CommandBar_Show(hwndCB, TRUE);
#endif // <BOOK_ADDON Chapter 9.5.1/> ****
// <BOOK_ADDON Chapter 9.5.1> **************************************
InitServer(hWnd);
// </BOOK_ADDON Chapter 9.5.1> **************************************
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
int wmId, wmEvent;
PAINTSTRUCT ps;
TCHAR szHello[MAX_LOADSTRING];
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_HELP_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_FILE_EXIT:
DestroyWindow(hWnd);
break;
// <BOOK_ADDON Chapter 9.5.1> **************************************
case ID_SENDPACKET:
#ifdef UNDER_CE
SendPacket(L"This was sent from Windows CE",
WM_SOCKET_SELECT,TEXT("192.168.55.1"));
#else
SendPacket(L"This was sent from Windows NT/98",
WM_SOCKET_SELECT,TEXT("192.168.55.5"));
#endif
break;
// </BOOK_ADDON Chapter 9.5.1> **************************************
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_CREATE:
#ifdef UNDER_CE // <BOOK_ADDON Chapter 9.5.1/> ****
hwndCB = CommandBar_Create(hInst, hWnd, 1);
CommandBar_InsertMenubar(hwndCB, hInst, IDM_MENU, 0);
CommandBar_AddAdornments(hwndCB, 0, 0);
#endif // <BOOK_ADDON Chapter 9.5.1/> ****
break;
// <BOOK_ADDON Chapter 9.5.1> **************************************
case WM_SOCKET_SELECT:
TCHAR wsu[100];
if (sizeof(TCHAR)==sizeof(WCHAR))
wsprintf(wsu,TEXT("%s"),(TCHAR *)wParam);
else
{
WCHAR *tTxt=(WCHAR *)wParam;
for (int i=0;i<(int)wcslen(tTxt);i++)
wsu[i]=(TCHAR)tTxt[i];
wsu[i]=0;
} // Some Unicode to ANSI conversion
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -