📄 pppclientdlg.cpp
字号:
// 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)(¶), 0, &dwThreadId);
hThread = CreateThread(NULL, NULL, TimeoutControl, (LPVOID)(¶), 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 + -