⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pppclientdlg.cpp

📁 客户端: 这是一个完整的基于Wince 4.1图形图象,网络通讯(C/S)模式下的商用程序源代码包.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// PPPClientDlg.cpp : implementation file
//

#include "stdafx.h"
#include "PPPClient.h"
#include "PPPClientDlg.h"
#include "texteditor.h"
#include "setpos.h"
#include "setsize.h"
#include "setserver.h"
#include "serverregister.h"
#include "softprotected.h"
#include "SoftRegister.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//static UINT indicators[]={
//	                      ID_SEPARATOR,
//						  ID_INDICATOR_CAPS,
//						  ID_INDICATOR_NUM,
//						  ID_INDICATOR_SCRL
//						};
static UINT BASED_CODE indicators[] =
{
    ID_MAINSTATUS,
	ID_SYSDATETIME,
    ID_PRGSTATUS
};
//static UINT indicators[] =
//{
//	ID_SEPARATOR,           // status line indicator
//	ID_INDICATOR_CAPS
//};
//for demo item
bool m_one_flag=false;
bool m_all_flag=false;
//for demo and main dialog 
bool m_show_demo_flag;
bool m_show_main_flag;
//for hotkey
bool m_hotkey_flag;
bool m_demo_hotkey_flag;
WORD MY_HOTKEY;
WORD MY_DEMO_HOTKEY;

CPPPClientDlg *m_main_dlg;
//
CString m_ini_pathname;

 SYSTEM_PARAMETER m_system_para;
//系统显示播放项类型,现暂为4种
TCHAR tmp_type_str[4][80]={_T("Text"),_T("Picture"),_T("Animation"),_T("Video")};
//非视频,动画播放项的显示方式:系统现有进入和退出两种显示效果
TCHAR tmp_fun_in_str[MAX_ADD_SHOWWAY][80]={
	                       _T("Random"),
	                       _T("Static"),
	                       _T("Flash"),
						   _T("Push Down"),
						   _T("Push Up"),
						   _T("Scan Down"),
						   _T("Scan Up"),
						   _T("Scan Center to UpDown"),
						   _T("Scan UpDown to Center"),						   
						   _T("Scan Right"),
						   _T("Scan Left"),
						   _T("Scan Center to LeftRight"),
						   _T("Scan LeftRigth to Center"),
						   _T("Vertical Right Blind"),
						   _T("Vertical Left Blind"),
						   _T("Horizontal Down Blind"),
						   _T("Horizontal Up Blind"),
						   _T("Scan/Corner1"),
						   _T("Scan/Corner2"),
						   _T("Scan/Corner3"),
						   _T("Scan/Corner4"),
						   //
						   _T("Push/Corner1"),
						   _T("Push/Corner2"),
						   _T("Push/Corner3"),
						   _T("Push/Corner4"),
						   _T("Rain"),
						   _T("Zoom IN"),
						   _T("Zoom OUT"),
						   _T("Push Left"),
						   _T("Push Right"),
						   //_T("Compress Left"),
						  // _T("Compress Right"),
						  // _T("Compress Up"),
						   //_T("Compress Down"),
						   _T("Half Fan"),
						   _T("Mosaic"),
						   _T("Full FAN"),
						   _T("Diamond"),
						   _T("Empty"),						  
						   _T("---------------")
                           };
TCHAR tmp_fun_out_str[MAX_ADD_SHOWWAY-1][80]={
	                        _T("Random"),
	                       _T("Static"),
	                       _T("Flash"),
						   _T("Push Down"),
						   _T("Push Up"),
						   _T("Scan Down"),
						   _T("Scan Up"),
						   _T("Scan Center to UpDown"),
						   _T("Scan UpDown to Center"),						   
						   _T("Scan Right"),
						   _T("Scan Left"),
						   _T("Scan Center to LeftRight"),
						   _T("Scan LeftRigth to Center"),
						   _T("Vertical Right Blind"),
						   _T("Vertical Left Blind"),
						   _T("Horizontal Down Blind"),
						   _T("Horizontal Up Blind"),
						   _T("Scan/Corner1"),
						   _T("Scan/Corner2"),
						   _T("Scan/Corner3"),
						   _T("Scan/Corner4"),
						   //
						   _T("Push/Corner1"),
						   _T("Push/Corner2"),
						   _T("Push/Corner3"),
						   _T("Push/Corner4"),
						   //_T("Rain"),
						   _T("Zoom IN"),
						   _T("Zoom OUT"),
						   _T("Push Left"),
						   _T("Push Right"),
						  // _T("Compress Left"),
						  // _T("Compress Right"),
						  // _T("Compress Up"),
						  // _T("Compress Down"),
						   _T("Half Fan"),
						   _T("Mosaic"),
						   _T("Full FAN"),
						   _T("Diamond"),
						   _T("Empty"),						
							_T("----------------")
							};
CPlayTableData DATA;
bool m_all_run_flag=false;
bool m_all_send_flag=false;
int m_edit_type;//-1:无效,0-Append ,1-Insert(Before),Modify:2
CPlayTableData m_cur_data;
//draw text
CList<LOGFONT,LOGFONT&> m_all_logfont;
//

int CALLBACK GetSystemAllFontname(CONST LOGFONT *lplf, 
                                 CONST TEXTMETRIC *lpntm, 
                                 DWORD nFontType, LPARAM lParam)
{
  // CList<LOGFONT,LOGFONT&> *fontlist=(CList<LOGFONT,LOGFONT&> *) lParam; ///???
   //pcombobox->AddString(lplf->lfFaceName);
   //
  // sFamilyCnt++;
   LOGFONT lg;
   lg=*lplf;
   m_all_logfont.AddTail(lg);
   
   return 1;
}
//
#define SOCKETBUFFSIZE  8192
//20480

#define SD_RECEIVE      0x00
#define SD_SEND         0x01
#define SD_BOTH         0x02
//读数据超时处理
 struct TPARA
{
	int		OutTime;
	SOCKET	s;
	//BOOL	*pbConnected;
	BOOL bExit;
	BOOL IsExit;
};
////读数据超时处理
DWORD CALLBACK TimeoutControl(LPVOID lpParm)
{
	TPARA* para = (TPARA*)lpParm;
	DWORD stime = GetTickCount();
	BOOL bTimeover = FALSE;

	while(!bTimeover)
	{
		if(para->bExit)
		{
			para->IsExit = TRUE;
			return 0;
		}

		Sleep(1);

		DWORD ntime = GetTickCount();
		if(labs(ntime - stime) >= para->OutTime) bTimeover = TRUE;
	}

	if(para->bExit)
	{
		para->IsExit = TRUE;
		return 0;
	}

	if(para->s != NULL)
	{
	//	para->pbConnected[0] = FALSE;
		shutdown(para->s, SD_RECEIVE);
		Sleep(5);
		closesocket(para->s);
	}

	para->IsExit = TRUE;
	return 0;
}
/****************************************************************
ConnectToServer用来连接到服务器
*****************************************************************/
int ConnectToServer(char ServerAddr[] ,int port,SOCKET *clientSocket)
{
	//WSADATA wsaData;
	
	//int Ret;

	//加载Winsock.dll
	//if((Ret=WSAStartup(MAKEWORD(1,1),&wsaData))!=0)
	//{
	//	printf("WSAStartup failed with error %d\n",Ret);
	//	return 0;
	//}

	//创建客户端socket
	if((*clientSocket = socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET)
	{
	//	printf("Create socket failed!\n");
		int errorno;
		errorno=WSAGetLastError();
		return 0;
	}
	BOOL val = TRUE;//???
    //SO_REUSEADDR选项就是可以实现端口重绑定的 SO_REUSEADDR SO_EXCLUSIVEADDRUSE
   if(setsockopt(*clientSocket,SOL_SOCKET,SO_REUSEADDR ,(char *)&val,sizeof(val))!=0)
    {
        //printf("error!setsockopt failed!\n");
		//ShowMessage(&m_meslist,"error!setsockopt failed!");
		closesocket(*clientSocket);
        return 0;
    }
	//inbuffer
	//设置接收缓冲区大小
	int nRecvBuf=SOCKETBUFFSIZE;//
    if(setsockopt(*clientSocket,SOL_SOCKET,SO_RCVBUF ,(char *)&nRecvBuf,sizeof(int))!=0)
    {
       
		closesocket(*clientSocket);
        return 0;
    }
	//发送缓冲区大小
	if(setsockopt(*clientSocket,SOL_SOCKET,SO_SNDBUF ,(char *)&nRecvBuf,sizeof(int))!=0)
    {       
		closesocket(*clientSocket);
        return 0;
    }
	int nNetTimeout=3000;//3秒
	//发送时限
	if(setsockopt(*clientSocket,SOL_SOCKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int))!=0)
	{
        closesocket(*clientSocket);
        return 0;
	}
	//接收时限
	if(setsockopt(*clientSocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int))!=0)
	{
        closesocket(*clientSocket);
        return 0;
	}
	//2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历 
    //TIME_WAIT的过程: 这很重要!!!
    BOOL bDontLinger = FALSE; 
    if(setsockopt(*clientSocket,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL))!=0)
	{
       closesocket(*clientSocket);
        return 0;
	}

	
	//如果在发送数据的时,希望不经历由系统缓冲区到socket缓冲区的拷贝而影响程序的性能
	int nZero=0;
	if(setsockopt(*clientSocket,SOL_SOCKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero))!=0)
	{
      closesocket(*clientSocket);
     return 0;
	}
	if(setsockopt(*clientSocket,SOL_SOCKET,SO_RCVBUF,(char *)&nZero,sizeof(int))!=0)
	{
      closesocket(*clientSocket);
      return 0;
	}
	//
	sockaddr_in serverAddr;
	//填充服务器端sockaddr_in 结构
	serverAddr.sin_family=AF_INET;
	// ServerHostAddr.sin_addr.s_addr=::inet_addr(m_system_para.m_server_ip);
	serverAddr.sin_addr.s_addr=inet_addr(ServerAddr);
	serverAddr.sin_port=htons(port);

	//连接到服务器
	if(connect(*clientSocket,(sockaddr *)&serverAddr,sizeof(serverAddr))==SOCKET_ERROR)
	{
		int errorno;
		errorno=WSAGetLastError();
	//	printf("Connect failed.\n");
		closesocket(*clientSocket);
		//WSACleanup();
		return 0;
	}
    //设置异步方式
	DWORD ul=1;
	ioctlsocket(*clientSocket,FIONBIO,&ul);

	return 1;
}

//向客户端发送数据的函数。
//参数1:连接socket;参数2:缓冲区指针;参数3:要发送的字节数,其实就是缓冲区中的数据数;
int WriteSocket(SOCKET fd,char *bp,int len)
{
	//return send(fd,bp,len,0);
	int cnt;
	int rc;
	cnt=len;
	//我觉得,之所以需要用一个while循环来发送数据,大概是因为send函数也许不能把指定数量数据
	//一次都发送完吧,所以需要用一个循环来反复地发送,直至所有的数据都发送完,或者是出错。
	while(cnt>0)
	{
		//send  The send function sends data on a connected socket.
		//send函数的返回值可用来表示已经成功地发送出去了多少数据,至于客户端能否成功地收到
		//这些数据,好像并不能在send函数的返回值中体现出来。其实,能否成功地收到数据是客户端
		//的事,跟服务器端无关。也许数据被客户端的防火墙拦截了,这样,客户端就永远也不能收到
		//这些数据了,不过,这些乱七八糟的事,服务器端可管不着。
		rc=send(fd,bp,cnt,0);
		if(rc==SOCKET_ERROR)
		{
		//	CString aa;
		//	aa="发送错误!\n";
		//	AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aa.GetBuffer(0),1);
		//	aa.ReleaseBuffer();
			int errorno;
			errorno=WSAGetLastError();
			return -1;
		}
		if(rc==0)
		{
			int errorno;
			errorno=WSAGetLastError();
			return len-cnt;
		}
		//发送完了一批数据后,缓冲区指针当然要向后移了。如果指定数量的数据已经发送完了,则
		//bp就指向缓冲区的末尾了。
		bp+=rc;
		//发送完了一批数据,则cnt(用来记录还没发送完的数据)的数值当然需要减去已经发送了的了。
		cnt-=rc;
	}
	return len;
	
}
//从服务端读取数据的函数。

//参数1:连接套接字;参数2:指向缓冲区的指针;参数3:缓冲区的长度;
//参数4:超时处理
int ReadSocket1(SOCKET fd,char *bp,int len,DWORD timeout)
{
/*
	HANDLE hThread;
	DWORD dwThreadId;
	TPARA para;

	para.OutTime = timeout;
	para.s = fd;//m_sSocket;
	para.bExit = FALSE;
	para.IsExit = FALSE;
//	para.pbConnected = &m_bConnected;
	//CreateThread(NULL, NULL, TimeoutControl, (LPVOID)(&para), 0, &dwThreadId);
   hThread = CreateThread(NULL, NULL, TimeoutControl, (LPVOID)(&para), 0, &dwThreadId);
	if (hThread == NULL)
	{
		return -1;
	}
	else
	{
		CloseHandle(hThread);//
	}*/
	/////////////////////////////////////////////
	int cnt;//用来记录缓冲区中的剩余可用空间。
	int rc;
	cnt=len;
	while(cnt>0)
	{
		//Platform SDK: Windows Sockets  The recv function receives data from a connected or bound socket.
		//Return Values  If no error occurs, recv returns the number of bytes received.
		//If the connection has been gracefully closed, the return value is zero. 
		//Otherwise, a value of SOCKET_ERROR is returned, and a specific error code 
		//can be retrieved by calling WSAGetLastError.
		//cnt参数的值被设定为缓冲区的长度值,所以,在网络速度足够好的情况下,读取cnt这么
		//多的字节,没问题。这样的话,此while循环只需要执行一次就会正常退出了。从而,我也
		//明白了while循环的作用,就是:用来保证一定要读取cnt这么多的字节,读不够数就
		//反复地读,直至读够数了,或者是此连接被关闭掉了。
		//我有一个疑问:如果客户端只发过来50个字节的数据,会怎么样呢?其实,这个问题,只需要查到合适的资料,就可以轻松解决,并无任何的难度可言。
		//答:?????? timeout process,haha~~
		rc=recv(fd,bp,cnt,0);

		if(rc==SOCKET_ERROR)
		{
			//CString aa;
			//aa="接收错误!\n";
			//AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aa.GetBuffer(0),1);
			//aa.ReleaseBuffer();
			//CloseHandle(hThread);//
			int errorno;
			errorno=WSAGetLastError();
			return -1;
		}

		//If the connection has been gracefully closed, the return value is zero.
		if(rc==0) 
		{
			int errorno;
			errorno=WSAGetLastError();
		//	CloseHandle(hThread);//
			return len-cnt;
		}
		//读取了一些数据之后,缓冲区指针也应该相应地增加。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -