📄 sendit.cpp
字号:
// SendIt.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "SendIt.h"
#include <commctrl.h>
// </BOOK_ADDON Chapter 9.6.1> **************************************
#include <af_irda.h>
// <BOOK_ADDON Chapter 9.6.1> **************************************
// <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
// <BOOK_ADDON Chapter 9.6.1> **************************************
DWORD WINAPI IrDAThread( LPVOID pParam )
{
SOCKET ClientSock; // Socket for the Client
// The IrDA address for the server
SOCKADDR_IRDA address = {AF_IRDA, 0, 0, 0, 0, "SendItReceiver"};
BYTE *tBuffer=NULL;
int endless;
PACKET_FILE filePacket;
BYTE *recBuf;
INT cbRead;
SOCKERR serr;
sCommand = socket(AF_IRDA, SOCK_STREAM, 0);
bind(sCommand, (struct sockaddr *)&address, sizeof(address));
listen(sCommand, 1);
endless=TRUE;
while (endless==TRUE)
{
// Wait for a client to contact us. Blocking call.
ClientSock = accept(sCommand, 0, 0);
if (ClientSock==SOCKET_ERROR)
{
endless=FALSE;
serr=WSAGetLastError();
}
// Receive a string from the client
recBuf=(BYTE *)&filePacket;
cbRead=recv(ClientSock, (char *)recBuf, sizeof(filePacket), 0);
if (ClientSock==INVALID_SOCKET)
endless=FALSE;
// Now comes the same code as in the WINSOCK Thread
EnterCriticalSection(&m_csec);
switch (filePacket.type)
{
case PACKET_TYPE_FILE:
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)filePacket.cbFile);
break;
case PACKET_TYPE_NACK:
endless=FALSE;
break;
default:
// Ignore Packet
break;
}
LeaveCriticalSection(&m_csec);
closesocket(ClientSock); // Close Client Socket
}
return(TRUE);
}
// </BOOK_ADDON Chapter 9.6.1> **************************************
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;
// <BOOK_ADDON Chapter 9.6.1> **************************************
if (0==0)
{
m_pCeThread = CreateThread( NULL, 0, IrDAThread,hwnd, 0L, &ThreadId);
}
else
{
// </BOOK_ADDON Chapter 9.6.1> **************************************
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);
} // <BOOK_ADDON Chapter 9.6.1/> **
//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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -