上线线程
//侦听线程
UINT WINAPI MyMainThread(LPVOID lPvoid)
{
UINT   m_Id = 0;
SOCKET   m_LisSocket = (SOCKET) lPvoid;
SOCKET   m_AccSocket = 0;
while(1)
{
   //等待客户连接
   if((m_AccSocket = accept(m_LisSocket,0,0)) == INVALID_SOCKET)
    break;

//启动客户签到线程
   _beginthreadex(NULL,0,MyChildThread,(LPVOID) m_AccSocket,0,&m_Id);
}
closesocket(m_LisSocket);
return 0;
}

void InterTrans(SOCKET s,LPCLIENTITEM pData , int ExecType)
{
//定位窗口唯一标识
sockaddr_in m_addr = {0};
int addrlen = sizeof(sockaddr_in);
getpeername(s,(sockaddr*) &m_addr,&addrlen);
char mTid[9] = {0};
memcpy(mTid, pData->m_SysInfo.ID, 8);
sprintf(pData->m_Title,"%d.%d.%d.%d:%s",
    m_addr.sin_addr.S_un.S_un_b.s_b1,
    m_addr.sin_addr.S_un.S_un_b.s_b2,
    m_addr.sin_addr.S_un.S_un_b.s_b3,
    m_addr.sin_addr.S_un.S_un_b.s_b4,
    mTid);

//确定命令对应窗口
char m_WndName[256] = {0};
if(ExecType == CONN_FILE_UP || ExecType == CONN_FILE_DL)
{
   //文件传输
   sprintf(m_WndName,"PCSHELL文件管理-%s",pData->m_Title);
}
else if(ExecType == CONN_FILE_MANA_SEND)
{
   sprintf(m_WndName,"PCSHELL文件管理-%s",pData->m_Title);
}
else if(ExecType == CONN_FILE_MANA_RECV)
{
   sprintf(m_WndName,"PCSHELL文件管理-%s",pData->m_Title);
   if(!SendKeepAlive(s)) return;
}
else if(ExecType == CONN_FILE_FRAM_SEND)
{
   sprintf(m_WndName,"PCSHELL屏幕监控-%s",pData->m_Title);
}
else if(ExecType == CONN_FILE_FRAM_RECV)
{
   sprintf(m_WndName,"PCSHELL屏幕监控-%s",pData->m_Title);
   if(!SendKeepAlive(s)) return;
}
else if(ExecType == CONN_FILE_TLNT_SEND)
{
   sprintf(m_WndName,"PCSHELL超级终端-%s",pData->m_Title);
}
else if(ExecType == CONN_FILE_TLNT_RECV)
{
   sprintf(m_WndName,"PCSHELL超级终端-%s",pData->m_Title);
   if(!SendKeepAlive(s)) return;
}
else if(ExecType == CONN_FILE_REGD_SEND)
{
   sprintf(m_WndName,"PCSHELL注册表管理-%s",pData->m_Title);
}
else if(ExecType == CONN_FILE_REGD_RECV)
{
   sprintf(m_WndName,"PCSHELL注册表管理-%s",pData->m_Title);
   if(!SendKeepAlive(s)) return;
}
else if(ExecType == CONN_FILE_PROC_SEND)
{
   sprintf(m_WndName,"PCSHELL进程管理-%s",pData->m_Title);
}
else if(ExecType == CONN_FILE_PROC_RECV)
{
   sprintf(m_WndName,"PCSHELL进程管理-%s",pData->m_Title);
   if(!SendKeepAlive(s)) return;
}
else if(ExecType == CONN_FILE_SERV_SEND)
{
   sprintf(m_WndName,"PCSHELL服务管理-%s",pData->m_Title);
}
else if(ExecType == CONN_FILE_SERV_RECV)
{
   sprintf(m_WndName,"PCSHELL服务管理-%s",pData->m_Title);
   if(!SendKeepAlive(s)) return;
}
else if(ExecType == CONN_FILE_MULT_SEND)
{
   sprintf(m_WndName,"PCSHELL视频监控-%s",pData->m_Title);
}
else if(ExecType == CONN_FILE_MULT_RECV)
{
   sprintf(m_WndName,"PCSHELL视频监控-%s",pData->m_Title);
   if(!SendKeepAlive(s)) return;
}

Sleep(500);

//查找窗口
HWND hWnd = FindWindow(NULL,m_WndName);
if(hWnd == NULL)
{
   Sleep(2000);
   hWnd = FindWindow(NULL,m_WndName);
   if(hWnd == NULL)
   {
    closesocket(s);
    return;
   }
}

//拷贝套接字
DWORD pId = 0;
GetWindowThreadProcessId(hWnd, &pId);
WSAPROTOCOL_INFO m_SocketInfo = {0};
if(WSADuplicateSocket(s, pId , &m_SocketInfo))
{
   closesocket(s);
   return ;
}

//发送套接字到进程
COPYDATASTRUCT ct = {0};
ct.lpData = &m_SocketInfo;
ct.cbData = sizeof(WSAPROTOCOL_INFO);
ct.dwData = ExecType;
SendMessage(hWnd,WM_COPYDATA,0,(LPARAM) &ct);
closesocket(s);
}

//
WSADuplicateSocket
这个函数用来传递一个WSAPROTOCOL_INFO结构带另外一个进程,其他进程就用这个结构打开一个socket就可以操作同一个socket了。函数声明:
int WSADuplicateSocket(
    SOCKET s,
    DWORD dwProcessId,
    LPWSAPROTOCOL_INFO lpProtocolInfo
);

通过WM_COPYDATA消息来实现不同进程中数据传递,传递SOCKET给子进程,子进程在控制端发出管理命令后立即运行
void CMainFrame::StartChildWork(LPCLIENTITEM pItem, char* pTitle, UINT nCmd,char* pExeName)
{
if(!pItem) return;

char m_Text[256] = {0};
sprintf(m_Text,"PCSHELL%s-%s", pTitle, pItem->m_Title);
HWND hWnd = ::FindWindow(NULL,m_Text);
if(hWnd)
{   //已存在该窗口
   ::BringWindowToTop(hWnd);
   return;
}

char* pFind = strrchr(m_Text,':');
if(pFind != NULL) *pFind = 0;

//启动新的子进程
char m_AppName[512] = {0};
char m_FileName[256];
strcpy(m_FileName, pExeName);
GetMyFilePath(m_FileName);
sprintf(m_AppName,"%s %s:%s",m_FileName,m_Text,pItem->m_SysInfo.ID);

STARTUPINFO st = {0};
st.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION pi = {0};
if(!CreateProcess(NULL , m_AppName , NULL ,
   NULL , TRUE , 0 , NULL , NULL , &st , &pi))
   return;

ExecCmd(pItem->m_WorkSocket , nCmd , 0);
}

一段关于共享套接字的描述
为了在进程间共享套接口,Windows Sockets 2引入了WSADuplicateSocket()
函数。共享套接口是通过对底层的套接口创建附加的套接口描述字实现的。该函
数的输入是本地的套接口描述字和目标进程的句柄。它返回一个仅在目标进程中
有效的新的套接口描述字(目标进程有可能就是原始进程)。这一机制既可以在
单线程Windows版本(例如Windows 3.1)中使用,也可以在占先的多线程
Windows版本(例如Windows 95和Windows NT)中使用。要注意的是,套接
口可以在一个进程的不同线程中共享而不需要使用WSADuplicateSocket()函数,
因为一个套接口描述字在进程的所有线程中都有效。
基于一个共享套接口的两个或者单个套接口描述字应该独立地使用套接口
I/O。然而Windows Sockets没有实现任何共享控制。因此,在一个共享套接口上
协调它们的操作是应用程序的责任。一个典型的使用共享套接口的例子是,有一
个进程专门负责创建套接口和建立连接,并把套接口交给其他负责信息交换的进
程。由于重新创建的是套接口描述字而不是底层的套接口,所以一切与套接口相
关的状态对于所有套接口描述字都是相同的。例如对一个套接口描述字应用
setsockopt()操作后,对所有的套接口描述字应用getsockopt()操作都可以看到这
一变化。一个进程有可能调用closesocket()函数关闭一个复制的套接口描述字,
于是该描述字就被清除了,然而,底层的套接口并不会被关闭,底层的套接口将
一直保持打开,直到最后的一个套接口描述字被关闭。
选择对共享套接口的通知可以使用WSAAsyncSelect()函数和
WSAEventSelect()函数。对任何共享的套接口描述字发出这些调用将会取消在这
一套接口上的所有注册事件,无论先前的注册使用了那个套接口描述字。因此,
如果应用程序想使进程A接收FD_READ事件,进程B接收FD_WRITE事件,
这是做不到的。如果应用程序确实需要使用这种紧密的协调方式,我们建议应用
程序开发者使用线程而不要使用进程。

PcShare也山寨

PcShare2005代码阅读(1)相关推荐

  1. ORB_SLAM2代码阅读(5)——Bundle Adjustment

    ORB_SLAM2代码阅读(5)--Bundle Adjustment 1. 说明 2. Bundle Adjustment(BA)的物理意义 3. BA的数学表达 4. BA的求解方法 4.1 最速 ...

  2. ORB_SLAM2代码阅读(3)——LocalMapping线程

    ORB_SLAM2代码阅读(3)--LocalMapping线程 1.说明 2.简介 3.处理关键帧 4. 地图点剔除 5. 创建新的地图点 6.相邻搜索 6.剔除冗余关键帧 1.说明 本文介绍ORB ...

  3. ORB_SLAM2代码阅读(4)——LoopClosing线程

    ORB_SLAM2代码阅读(4)--LoopClosing线程 1.说明 2.简介 3.检测回环 4.计算Sim3 4.1 为什么在进行回环检测的时候需要计算相似变换矩阵,而不是等距变换? 4.2 累 ...

  4. ORB_SLAM2代码阅读(2)——tracking线程

    ORB_SLAM2代码阅读(2)--Tracking线程 1. 说明 2. 简介 2.1 Tracking 流程 2.2 Tracking 线程的二三四 2.2.1 Tracking 线程的二种模式 ...

  5. ORB_SLAM2代码阅读(1)——系统入口

    ORB_SLAM2代码阅读(1)--系统简介 1.说明 2.简介 3.stereo_kitti.cc 4.SLAM系统文件(System.cc) 4.1 构造函数System() 4.2 TrackS ...

  6. 深度学习项目代码阅读建议

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达本文转自|机器学习实验室 犹豫很久要不要把读代码这个事情专门挑出来写 ...

  7. JavaScript权威Douglas Crockford:代码阅读和每个人都该学的编程

    作者:Peter Seibel 关于JavaScript Seibel:在程序学习之路上有哪些令你后悔的事情? Crockford:我了解一些语言,但却一直没有机会使用.我花了不少时间学习APL并了解 ...

  8. MFC按钮CXPButton类,代码阅读起来还是挺不错的

    在操手MFC的时候,经常会抱怨MFC界面不如其他的框架或语言,比如VB,C#等等,面对MS在系统上的不断更新换代,我们也越来越追求软件的视觉效果,譬如我们会更喜欢win7下的玻璃效果,看起来很炫. 在 ...

  9. 《代码阅读方法与实践之读书笔记之一》

    <代码阅读方法与实践之读书笔记之一> 阅读代码是程序员的基本技能,同时也是软件开发.维护.演进.审查和重用过程中不可或缺的组成部分.<代码阅读方法与实践之读书笔记之一>这本书围 ...

  10. 《代码阅读方法与实践》阅读笔记一

    第三本书我选择了代码阅读方法与实践,说实话,觉得三本书里面最好的就是这一本书了,每一段话,每一段代码打偶让我受益匪浅.下面是我的收获: 1.1为什么以及如何阅读代码  将代码作为文献:要养成一个习惯, ...

最新文章

  1. MSRA副院长周明博士:四大研究领域揭示自然语言技术的奥秘
  2. java.sql.Connection.close() vs null
  3. SharePoint 出现无法识别的属性“type”
  4. 灰帽黑客:正义黑客的道德规范、渗透测试、攻击方法和漏洞分析技术(第3版)
  5. centos6.4使用man查找命令时,报错No manual entry for xxxx
  6. 【译】10 years Blockchain. The Race is on: Blockchain vs. Tangle vs. Hashgraph
  7. 赵英时遥感原理分析和应用课件_细数5种停车场防砸车技术原理分析与应用
  8. 安装mysql准备执行页面_mysql 安装
  9. 如何优雅处理 async await 错误——解读小而美的 await-to-js 库
  10. java 线程池 包_Java并发包下线程池类小结
  11. Windows Nano Server安装配置详解06:在物理机中部署NanoServer
  12. Android开发笔记(七十九)资源与权限校验
  13. springboot如何快速访问templates下的html
  14. VS2008 sp1中文版下载地址
  15. Win11打印机脱机了怎么重新连接?Win11打印机脱机的解决方法
  16. 日本性价比旅馆分析报告
  17. Linux下的常用软件集锦
  18. 添加了排比句的狗屁不通生成器
  19. 操作系统 第二章 进程的描述与控制(4)进程同步(重点)
  20. 茴字的四种写法—移动适配方案的进化

热门文章

  1. buuctf easyweb
  2. 超强功能WebSSH安装,解决Web远程SSH终端
  3. 技嘉服务器主板装系统,技嘉主板bios设置图解教程
  4. 成功解决 3DMAX报错:3D MAX application 已停止工作的解决方法
  5. 手把手教你制作可以上线官方商店的微信动态表情包
  6. Hash 表的时间复杂度为什么是 O(1)(面试版)
  7. c语言万能编程模板_C语言实现模板
  8. 关于STVD有时候会无法追踪到变量或函数定义的位置
  9. 【图像去噪】基于自适应布谷鸟算法优化维纳滤波器实现多光谱图像去噪附matlab代码
  10. vmware虚拟机卸载教程