📄 mysock.cpp
字号:
// MySock.cpp: implementation of the CMySock class.
//
//////////////////////////////////////////////////////////////////////
#include "j_shk.h"
#include "stdafx.h"
#include "MySock.h"
#include "j_shkDlg.h"
#include "ourgame.h"
#include <winsock2.h>
//#include "iphlpapi.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
static char SHKIndex[]={
'3','4','5','6','7','8','9','0','J','Q','K','A','2',//13
'3','4','5','6','7','8','9','0','J','Q','K','A','2',
'3','4','5','6','7','8','9','0','J','Q','K','A','2',
'3','4','5','6','7','8','9','0','J','Q','K','A','2',
'F','Z',
'3','4','5','6','7','8','9','0','J','Q','K','A','2',
'3','4','5','6','7','8','9','0','J','Q','K','A','2',
'3','4','5','6','7','8','9','0','J','Q','K','A','2',
'3','4','5','6','7','8','9','0','J','Q','K','A','2',
'F','Z' }; //双扣的牌索引
static char SHKIndexCPL[]={
0,1,2,3,4,5,6,7,8,9,10,11,12,
0,1,2,3,4,5,6,7,8,9,10,11,12,
0,1,2,3,4,5,6,7,8,9,10,11,12,
0,1,2,3,4,5,6,7,8,9,10,11,12,
13,14,
0,1,2,3,4,5,6,7,8,9,10,11,12,
0,1,2,3,4,5,6,7,8,9,10,11,12,
0,1,2,3,4,5,6,7,8,9,10,11,12,
0,1,2,3,4,5,6,7,8,9,10,11,12,
13,14 }; //。。。。。。
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMySock::CMySock(CJ_shkDlg* pDlg)
{
m_pDlg=pDlg;
m_pThreadPause=new CEvent(true,true);
m_pThreadPause->ResetEvent();//
}
CMySock::~CMySock()
{
m_ThreadEnd.SetEvent();
::WaitForSingleObject(m_MySockEnd,6000);//INFINITE
closesocket(m_Socket);
WSACleanup();
delete m_pThreadPause;
}
bool CMySock::CreateSock()
{
WSADATA wsaData;
DWORD dwBufferLen[10] ;
DWORD dwBufferInLen= 1 ;
DWORD dwBytesReturned = 0;
int ret = WSAStartup(MAKEWORD(2,2), &wsaData);
if(ret != 0) {
AfxMessageBox("初始化套接字失败!");
return false;
}//else
// m_pView->PutMs("初始化套接字\r\n");
m_Socket=socket( AF_INET , SOCK_RAW , IPPROTO_IP);
if(m_Socket==INVALID_SOCKET){
AfxMessageBox("创建一个监听套接字失败!");
closesocket(m_Socket);
WSACleanup();
return FALSE;
}
//else
// m_pView->PutMs("创建一个监听套接字\r\n");
//int rcvtimeo = 5000 ; // 5 sec insteadof 45 as default
//if(setsockopt(m_Socket,SOL_SOCKET,SO_RCVTIMEO,
// (const char *)&rcvtimeo,sizeof(rcvtimeo) )
// == SOCKET_ERROR){
// AfxMessageBox("定制SOCKET出错 SOL_SOCKET") ;
// closesocket(m_Socket);
// WSACleanup();
// return false;
//}
//else
// m_pView->PutMs("定制SOCKET,参数SOL_SOCKET\r\n");
SOCKADDR_IN localaddr;
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(SOCKETPORT);
char buf[2048];
DWORD dwBytesRet;
// int ret;
ret = WSAIoctl(m_Socket, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048,
&dwBytesRet, NULL, NULL);
if (ret == SOCKET_ERROR)
{
AfxMessageBox("WSAIoctl(SIO_ADDRESS_LIST_QUERY)");
closesocket(m_Socket);
WSACleanup();
return FALSE;
}
SOCKET_ADDRESS_LIST *slist=(SOCKET_ADDRESS_LIST *)buf;
localaddr.sin_addr.s_addr = //htonl(INADDR_ANY);//0
((SOCKADDR_IN *)slist->Address[0].lpSockaddr)->sin_addr.s_addr;
if(bind(m_Socket,(PSOCKADDR)&localaddr,sizeof(sockaddr))==SOCKET_ERROR){
AfxMessageBox("绑定地址失败!");
closesocket(m_Socket);
WSACleanup();
return FALSE;
}
//else
// m_pView->PutMs("绑定地址\r\n");
if(SOCKET_ERROR==
WSAIoctl(m_Socket,SIO_RCVALL , &dwBufferInLen, sizeof(dwBufferInLen),
&dwBufferLen, sizeof(dwBufferLen),
&dwBytesReturned , NULL , NULL ) )
{
AfxMessageBox("定制SOCKET错误SIO_RCALL");
return false;
}
//char szHostName[MAX_PATH];
//gethostname(szHostName, sizeof(szHostName)) ;
//HOSTENT *pHE = gethostbyname(szHostName);
char szSource[16];
m_IpAddr=localaddr.sin_addr;
char *pSource = inet_ntoa(localaddr.sin_addr);
memcpy(szSource,pSource,16);
//char szSource1[16];
//strcpy( szSource1 , pSource ) ;
//m_pView->PutMs(szSource);
//m_pView->PutMs("\r\n");
//m_pView->PutMs("SOCKET成功,启动监听线程....\r\n");
AfxBeginThread(SocktThread,(LPVOID)this);
return true;
}
int CMySock::GetInterface(SOCKET s, SOCKADDR_IN *ifx, int num)
{
return 0;
}
UINT SocktThread(LPVOID pParam)
{
CMySock* pMySock=(CMySock*)pParam;
char buf [65535],*pdata;//data[1000];
int iRet ;
// DWORD dwErr ;
IPHEADER *pIpHeader=NULL;
TCPHEADER *pTcpHeader=NULL;
char nc[10];//,szErr[50];
CString cs;
unsigned int i=0;
while(1){
if(::WaitForSingleObject(pMySock->m_ThreadEnd,0)
==WAIT_OBJECT_0)//为了在主程序停止的时候停止线程
break;
if(::WaitForSingleObject(*(pMySock->m_pThreadPause),0)
==WAIT_OBJECT_0){
//pMySock->m_pView->PutMs("pause");
continue;//立即回到while;
}
memset( buf , 0 , sizeof(buf) ) ;
//..........以下代码为调试..............
iRet = recv( pMySock->m_Socket,buf,sizeof(buf),0);
if( iRet == SOCKET_ERROR){
AfxMessageBox("Error:SOCKET ERROR,请记下错误告诉作者");
continue;
}
pIpHeader = (IPHEADER *)buf;
if(iRet!=ntohs(pIpHeader->total_len)){
AfxMessageBox("Error:长度ERROR.计牌器可能要出错,请记下错误");
continue;
}
//........................
pIpHeader = (IPHEADER *)buf;
if(pIpHeader->proto!=6) continue;
i=iRet-40;
//调试代码......用于保持数据...
static bool b=false;
if(pMySock->m_pDlg->m_bCp){
if(b==false){
pMySock->m_pDlg->m_csRecord.Empty();
b=true;
}
if((pIpHeader->sourceIP!=pMySock->m_IpAddr.S_un.S_addr)&&
(pIpHeader->destIP !=pMySock->m_IpAddr.S_un.S_addr))
continue;
if( ((ntohs(pTcpHeader->tcp_source_port)!=3008)&&
(ntohs(pTcpHeader->tcp_dest_port)!=3008)) |
((ntohs(pTcpHeader->tcp_source_port)!=3003)&&
(ntohs(pTcpHeader->tcp_dest_port)!=3003))
)
continue;
pTcpHeader= (TCPHEADER*)(buf+pIpHeader->header_len*4);
pdata=(char*)((char*)pTcpHeader+(pTcpHeader->tcp_hlen)*4);
pMySock->m_pDlg->m_csRecord+="原端口:";
sprintf( nc,"%d",ntohs(pTcpHeader->tcp_source_port));
pMySock->m_pDlg->m_csRecord+=nc;
pMySock->m_pDlg->m_csRecord+=" 目标端口:";
sprintf( nc,"%d",ntohs(pTcpHeader->tcp_dest_port));
pMySock->m_pDlg->m_csRecord+=nc;
pMySock->m_pDlg->m_csRecord+=" 数据包长度";
sprintf( nc,"%u",i);
pMySock->m_pDlg->m_csRecord+=nc;
pMySock->m_pDlg->m_csRecord+="\r\n";
for(unsigned int j=0;j<i;j++){//j<w
sprintf( nc,"%u",(unsigned char)pdata[j]);
pMySock->m_pDlg->m_csRecord+=nc;
pMySock->m_pDlg->m_csRecord+=" ";
}
pMySock->m_pDlg->m_csRecord+="\r\n";}
else
b=false;
//调试代码......用于保持数据...//*/
if(pIpHeader->destIP !=pMySock->m_IpAddr.S_un.S_addr)
continue;
pTcpHeader= (TCPHEADER*)(buf+pIpHeader->header_len*4);
pdata=(char*)((char*)pTcpHeader+(pTcpHeader->tcp_hlen)*4);
if(i==0){
//调试代码
//AfxMessageBox("Error:0长度数据包");
//.........
continue;//有可能
}
//3008=双扣..//3003=斗地主..//2002=聊天..
//..............
if( (ntohs(pTcpHeader->tcp_source_port)==3008) )
ProceSHKTcp(pdata,pMySock,i);
else if( (ntohs(pTcpHeader->tcp_source_port)==3003) )
ProceDZHTcp(pdata,pMySock,i);
//..............
Sleep( 100 ) ; // 停一停
}//end while(1);/*/
pMySock->m_MySockEnd.SetEvent();
return 0;
}
int ProceSHKTcp(char* pdata,CMySock* pMySock,unsigned int i)
{
SHKHEADER* pSHK=NULL;
OURGAMEHEADER* pOURGAME=NULL;
SHKBEGINHEARER* pSHKBEGIN=NULL;
CString cs="";
unsigned int w;
static char begin=0;//自己打牌的编号(0-4)
while(1){
pOURGAME=(OURGAMEHEADER*)pdata;
if( (pOURGAME->flag1==0)&&(pOURGAME->flag2==0)&&
(pOURGAME->flag3==0) ) break;//更换游戏室的数据,退出
else if(pOURGAME->flag4==128) w=(4+4+4+pOURGAME->allbyte);
else if(pOURGAME->flag4==0) w=(4+4+ pOURGAME->allbyte);
else {
//char szErr[50];
//memset(szErr,0,sizeof(szErr));
//sprintf(szErr,"%u,%u,%u,%u,%u",pdata[0],pdata[1],
// pdata[2],pdata[3],pdata[4]);
//AfxMessageBox(szErr);
break;}//一个未知的数据,退出。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -