【网络通信】Wince 和 PC 通过USB 用Socket 进行通信

【网络通信】Wince 和 PC 通过USB 用Socket 进行通信

转注:未经验证,但可能有用

分类: 【网络通信】 86人阅读 评论(1) 收藏 举报

网上资料比较少或者说讲的不太详细,现在进行总结下,刚毕业没接触过WINce,不过和MFC差不多,现在进入正题



刚开始我的疑惑是Wince是如何和PC进行通信的,以及能在USB模式下进行socket通信,后来知道,当你将(要安装Windows Mobile 设备中心)USB把Wince和PC相连接的时候,我在想WInce的IP如何和PC的IP在一个网段,要知道connect socket要在一个网段的,后来知道Wince用USB连接后(我猜是有虚拟网卡)会给WINce默认一个192.168.55.101的IP, 255.255.255.0的子网掩码,以及192.168.55.100的网关(你可以在连接USB后用wince的command和ipconfig下),然后网上查找会给电脑一个192.168.55.100的IP,我在想那么多Wince,而我的需求是不能再界面上配置IP,那么多wince设备连接,IP是如何分配的。我需要在程序里写死,后来知道Wince的IP是固定的,这样就简单了。


好知道了IP和原理接下去是如何进行通信了,你会说,和还不一样,和MFC的Socket一样呗。我开始也是这么理解的,网上资料又少,绕了很多路,在Wince和PC用USB通信的情况下,Wince只能做客户端,PC只能做服务端(我反过来试了下没能成功),谷歌上写的也是如此,这样害我的工作一下子变麻烦了。


========================

下面先贴出Wince客户端的代码:

  1. WORD wVersionRequested;  
  2.     WSADATA wsaData;  
  3.     int err;  
  4.   
  5.     fd_set fdRead;  
  6.     timeval TimeOut;  
  7.     TimeOut.tv_sec=0;  
  8.     TimeOut.tv_usec=500;  
  9.   
  10.     int nNetTimeout = 500;  
  11.   
  12.     wVersionRequested = MAKEWORD( 1, 1 );  
  13.   
  14.     err = WSAStartup( wVersionRequested, &wsaData );  
  15.     if ( err != 0 ) {  
  16.         return 0;  
  17.     }  
  18.     //WinSock DLL 版本是否低于1.1   
  19.   
  20.     if ( LOBYTE( wsaData.wVersion ) != 1 ||  
  21.         HIBYTE( wsaData.wVersion ) != 1 ) {  
  22.             WSACleanup( );  
  23.             return 0;   
  24.     }  
  25.   
  26.   
  27.     SOCKET sockClient;  
  28.     int     nRet = 0;  
  29.     DWORD   dwErr = 0;  
  30.     byte    msg[1024];  
  31.     byte    recvData[255];  
  32.   
  33.     SOCKADDR_IN addrSrv;  
  34.     addrSrv.sin_addr.S_un.S_addr=inet_addr("192.168.55.100");  
  35.     addrSrv.sin_family=AF_INET;  
  36.     addrSrv.sin_port=htons(26023);  
  37.   
  38.     sockClient=socket(AF_INET,SOCK_STREAM,0);  
  39.   
  40.     while(true)  
  41.     {  
  42.         if(WAIT_OBJECT_0 == WaitForSingleObject(pDlg->m_hReadHandle, 500))  
  43.         {  
  44.             SetEvent(pDlg->m_hExitReadHandle);  
  45.             break;  
  46.         }  
  47.           
  48.         //向服务器发出连接请求   
  49.         nRet = connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));  
  50.         if(SOCKET_ERROR == nRet)  
  51.         {  
  52.             //pDlg->GetDlgItem(IDC_STATIC_MSG)->SetWindowText(_T("USB连接失败,请检查数据线!"));   
  53.             //dwErr = WSAGetLastError();   
  54.             Sleep(1000);  
  55.             continue;  
  56.         }  
  57.   
  58.         int nLen = 0;  
  59.         ZeroMemory(&msg, sizeof(msg));  
  60.         pDlg->GetDlgItem(IDC_STATIC_MSG)->SetWindowText(_T("USB已连接。"));  
  61.   
  62.         while(true)  
  63.         {  
  64.             if(WAIT_OBJECT_0 == WaitForSingleObject(pDlg->m_hReadHandle, 500))  
  65.             {  
  66.                 SetEvent(pDlg->m_hExitReadHandle);  
  67.                 goto END;         
  68.             }  
  69.             int nRecvLen = 0;  
  70.             ZeroMemory(&recvData, sizeof(recvData));  
  71.   
  72. //          FD_ZERO(&fdRead);   
  73. //          FD_SET(sockClient,&fdRead);   
  74. //          int ret=::select(0,&fdRead,NULL,NULL,&TimeOut);   
  75. //          if (ret == 0)   
  76. //          {   
  77. //              closesocket(sockClient);   
  78. //              sockClient=socket(AF_INET,SOCK_STREAM,0);      
  79. //              break;   
  80. //    
  81. //          }   
  82.   
  83.             int backcon = setsockopt(sockClient,SOL_SOCKET, SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));   
  84.   
  85.             nRecvLen = recv(sockClient,(char*)&recvData,sizeof(recvData),0);  
  86.   
  87.   
  88.             if (SOCKET_ERROR == nRecvLen)  
  89.             {  
  90.                 //pDlg->GetDlgItem(IDC_STATIC_MSG)->SetWindowText(_T("USB连接失败或无发行系统无初始化操作!"));   
  91.                 closesocket(sockClient);  
  92.                 sockClient=socket(AF_INET,SOCK_STREAM,0);  
  93.                 break;  
  94.             }  
  95.             if (nRecvLen == 0)  
  96.             {  
  97.   
  98.                 TRACE(L"Recv 0\n");  
  99.                 Sleep(50);  
  100.                 continue;  
  101.             }  
  102.   
  103.             if(/*SOCKET_ERROR != nRecvLen && */0 != nRecvLen)  
  104.             {  
  105.                 if(0 == nLen && 0x31 == recvData[0] )  
  106.                 {  
  107.                     memcpy(msg, recvData, nRecvLen);  
  108.                     nLen += nRecvLen;  
  109.                 }  
  110.                 else if(0 < nLen)  
  111.                 {  
  112.                     memcpy(msg + nLen, recvData, nRecvLen);  
  113.                     nLen += nRecvLen;  
  114.                 }  
  115.   
  116.   
  117.   
  118.                 if(0 < nLen )  
  119.                 {  
  120.                     //   
  121.                     int SInitLen = recvData[1] * 0x100 + recvData[2];  
  122.                     //   
  123.                     if (SInitLen == nLen)  
  124.                     {  
  125.   
  126.                         if(pDlg->AnalyseInitMsg(msg, nLen))  
  127.                         {  
  128.                             send(sockClient, "ok", 3, 0);  
  129.                             pDlg->GetDlgItem(IDC_STATIC_MSG)->SetWindowText(_T("初始化完成,正在返回!"));  
  130.                             Sleep(500);  
  131.                               
  132.                             pDlg->PostMessage(WM_INITSUCCESS, 0, 0);                                   
  133.                         }  
  134.                         else  
  135.                         {  
  136.                             send(sockClient, "error", 6, 0);  
  137.                             Sleep(500);  
  138.                             //pDlg->GetDlgItem(IDC_STATIC_USBINIT)->SetWindowText(_T("初始化失败,重新获得配置信息。"));   
  139.                             pDlg->GetDlgItem(IDC_STATIC_MSG)->SetWindowText(_T("初始化失败,重新获得配置信息。"));  
  140.   
  141.                         }  
  142.   
  143.                     }  
  144.                 }  
  145.   
  146.             }  
  147.   
  148.   
  149.         }  
  150.     }  
WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	fd_set fdRead;
	timeval TimeOut;
	TimeOut.tv_sec=0;
	TimeOut.tv_usec=500;

	int nNetTimeout = 500;

	wVersionRequested = MAKEWORD( 1, 1 );

	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
		return 0;
	}
	//WinSock DLL 版本是否低于1.1

	if ( LOBYTE( wsaData.wVersion ) != 1 ||
		HIBYTE( wsaData.wVersion ) != 1 ) {
			WSACleanup( );
			return 0; 
	}


	SOCKET sockClient;
	int		nRet = 0;
	DWORD	dwErr = 0;
	byte	msg[1024];
	byte	recvData[255];

	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr=inet_addr("192.168.55.100");
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(26023);

	sockClient=socket(AF_INET,SOCK_STREAM,0);

	while(true)
	{
		if(WAIT_OBJECT_0 == WaitForSingleObject(pDlg->m_hReadHandle, 500))
		{
			SetEvent(pDlg->m_hExitReadHandle);
			break;
		}
		
		//向服务器发出连接请求
		nRet = connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
		if(SOCKET_ERROR == nRet)
		{
			//pDlg->GetDlgItem(IDC_STATIC_MSG)->SetWindowText(_T("USB连接失败,请检查数据线!"));
			//dwErr = WSAGetLastError();
			Sleep(1000);
			continue;
		}

		int nLen = 0;
		ZeroMemory(&msg, sizeof(msg));
		pDlg->GetDlgItem(IDC_STATIC_MSG)->SetWindowText(_T("USB已连接。"));

		while(true)
		{
			if(WAIT_OBJECT_0 == WaitForSingleObject(pDlg->m_hReadHandle, 500))
			{
				SetEvent(pDlg->m_hExitReadHandle);
				goto END;		
			}
			int nRecvLen = 0;
			ZeroMemory(&recvData, sizeof(recvData));

// 			FD_ZERO(&fdRead);
// 			FD_SET(sockClient,&fdRead);
// 			int ret=::select(0,&fdRead,NULL,NULL,&TimeOut);
// 			if (ret == 0)
// 			{
// 				closesocket(sockClient);
// 				sockClient=socket(AF_INET,SOCK_STREAM,0);	
// 				break;
// 
// 			}

			int backcon = setsockopt(sockClient,SOL_SOCKET, SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int)); 

			nRecvLen = recv(sockClient,(char*)&recvData,sizeof(recvData),0);


			if (SOCKET_ERROR == nRecvLen)
			{
				//pDlg->GetDlgItem(IDC_STATIC_MSG)->SetWindowText(_T("USB连接失败或无发行系统无初始化操作!"));
				closesocket(sockClient);
				sockClient=socket(AF_INET,SOCK_STREAM,0);
				break;
			}
			if (nRecvLen == 0)
			{

				TRACE(L"Recv 0\n");
				Sleep(50);
				continue;
			}

			if(/*SOCKET_ERROR != nRecvLen && */0 != nRecvLen)
			{
				if(0 == nLen && 0x31 == recvData[0] )
				{
					memcpy(msg, recvData, nRecvLen);
					nLen += nRecvLen;
				}
				else if(0 < nLen)
				{
					memcpy(msg + nLen, recvData, nRecvLen);
					nLen += nRecvLen;
				}



				if(0 < nLen )
				{
					//
					int SInitLen = recvData[1] * 0x100 + recvData[2];
					//
					if (SInitLen == nLen)
					{

						if(pDlg->AnalyseInitMsg(msg, nLen))
						{
							send(sockClient, "ok", 3, 0);
							pDlg->GetDlgItem(IDC_STATIC_MSG)->SetWindowText(_T("初始化完成,正在返回!"));
							Sleep(500);
							
							pDlg->PostMessage(WM_INITSUCCESS, 0, 0);									
						}
						else
						{
							send(sockClient, "error", 6, 0);
							Sleep(500);
							//pDlg->GetDlgItem(IDC_STATIC_USBINIT)->SetWindowText(_T("初始化失败,重新获得配置信息。"));
							pDlg->GetDlgItem(IDC_STATIC_MSG)->SetWindowText(_T("初始化失败,重新获得配置信息。"));

						}

					}
				}

			}


		}
	}
  1. END:  
  2. <SPAN style="WHITE-SPACE: pre"> </SPAN>//关闭套接字   
  3. <SPAN style="WHITE-SPACE: pre"> </SPAN>closesocket(sockClient);  
  4. <SPAN style="WHITE-SPACE: pre"> </SPAN>WSACleanup();  
  5.   
  6.   
  7. <SPAN style="WHITE-SPACE: pre"> </SPAN>return 0;  
  8. }  
END:
	//关闭套接字
	closesocket(sockClient);
	WSACleanup();


	return 0;
}

这里你发现我设置的IP是192.168.55.100

而不是192.168.55.101的WinceIP ,为什么用100网关而不用101Wince的100,因为PC端会虚拟一个100的IP对应

在这里你会发现,当你连接USB后connect会成功,Socket默认是阻塞模式的,你会发现执行到recv的时候它却直接返回-1(当你起了服务端后,recv会死等,正常情况);

原理这里的connect不是真正的连接成功了,所以这里recv后你还应该去做判断是否真的连接成功了,这里我开始用了select模式超时,依然无法判断是否真的连接成功。

所以我这里占时做的是如果recv-1;直接从新socket去connect,(这里不知道你会不会发现问题,当用户将USB连接后而没起服务端,这里你就会反复socket创建,但是socket线程池,即原先的socket好像是2分钟才回收,根本来不及回收,不会发现过一会后socket的返回值会很大(1,3,5,7......)如此增加,我在想最终肯定会超出上限奔溃,),有人可能会说那在recv失败后线sleep下啊。多等待让socket回收啊。可惜我的用户是国安的老年人,要在不小心掉了数据线后再次插上后马上重连(recv阻塞模式死等会很久),没办法,我只能另外起线程,判断用户多久一直没操作就关闭socket不在重新创建,操作的时候如何没connect上在创建socket。这里我也采用了超时recv,因为需求不能在recv死等太久。


当然由于没用过select和时间有限,那时候的思路是这样的,采用select超时模式,因为当服务端没起来。connect是假的connect,应该和(window设备中心的一个虚拟的连接上了),这时候判断recv返回-1的情况下是否超出了超时时间,没有超出超时时间,那说明直接返回的recv-1,是前面connect是假连接。


======================================下面是服务端


  1. static int nInitCount = 0;  
  2.     //加载套接字socket(插座)   
  3.     WORD wVersionRequested;                 //typedef unsigned short WORD;   
  4.     WSADATA wsaData;                        //结构体  typedef struct WSAData   WSADATA    。typedef WSADATA FAR *LPWSADATA;   
  5.     int nReg = 0;                           //错误函数的检测数值传递给nReg   
  6.     SOCKET sockSvr;                         //typedef _W64 unsigned int 、、SOCKET;     
  7.     SOCKADDR_IN addrSrv;  
  8.     int nErrCode = 0;  
  9.     int bExit = 0;  
  10.     unsigned long ul = -1;  
  11.   
  12.     struct timeval timeout={2,0};  
  13.     fd_set rfd;  
  14.     int nfds;  
  15.   
  16.     wVersionRequested = MAKEWORD(1, 1);     //请求.1版本socket   
  17.   
  18.     nReg = WSAStartup(wVersionRequested,&wsaData);//初始化   
  19.     if (0 != nReg)  
  20.     {  
  21.         printf("err code :%d",WSAGetLastError());  
  22.         return 0;  
  23.     }  
  24.     if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)  
  25.     {  
  26.         printf("VERSION DIFF");  
  27.         WSACleanup();  
  28.         return 0;  
  29.     }  
  30.   
  31.     sockSvr = socket(AF_INET, SOCK_STREAM, 0); //socket(IN int af,IN int type,IN int protocol); SOCK_STREAM(使用TCP协议而不是UDP)创建socket   
  32. //  nErrCode = ioctlsocket(sockSvr, FIONBIO, (unsigned long*)&ul);                 //设置套接字非阻塞模式   
  33. //  if (nErrCode == SOCKET_ERROR)   
  34. //  {   
  35. //      //设置套接字非阻塞模式,失败处理   
  36. //  }   
  37.     if (INVALID_SOCKET == sockSvr)             //判断sock是否创建成功   
  38.     {  
  39.         printf("err code :%d",WSAGetLastError());//获取错误类型函数WSAGetLastError()   
  40.         return 0;  
  41.     }  
  42.   
  43.     //设定内部接口   
  44.     addrSrv.sin_family = AF_INET;                                       //启动协议   
  45.     addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);                   //绑定地址   
  46.     addrSrv.sin_port = htons(26023);                                        //绑定端口   
  47.   
  48.     nReg = bind(sockSvr, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));        //内部接口设定完成将整体绑定到服务器sockSvr   
  49.     if (SOCKET_ERROR == nReg)                                           //判断绑定是否成功   
  50.     {  
  51.         nErrCode = WSAGetLastError();  
  52.         if (nErrCode == WSAEADDRINUSE)                                   //如果端口被占用   
  53.         {  
  54.             //printf("err code :%d,port is already used ",nErrCode);   
  55.         }  
  56.         else  
  57.         {  
  58.   
  59.         }  
  60.             //printf("err code :%d",nErrCode);   
  61.         return 0;  
  62.     }  
  63.   
  64.     //监听,准备接收   
  65.     listen(sockSvr, 5);                                 //最多同时监听个sock   
  66.   
  67.     CString strMsg = _T("");  
  68.     while (TRUE)  
  69.     {  
  70.         if (WAIT_OBJECT_0 == WaitForSingleObject(dlg->m_hEventSocket,100))//结束押运箱   
  71.         {  
  72.             closesocket(sockSvr);                                                //关闭正在于客户端通信的服务端sock   
  73.             WSACleanup();//初始化关闭   
  74.             SetEvent(dlg->m_HEventExitSocket);  
  75.             return 0;  
  76.         }  
  77.         if (dlg->m_bUsbinitingTer)  
  78.         {  
  79.             if (nInitCount == 0)  
  80.             {  
  81.                 strMsg.Format(_T("正在初始化%s手持终端,请等待..."),dlg->m_strTerInitName);  
  82.                 dlg->m_pOutPutView->AddWarnInfo(strMsg,true);  
  83.             }  
  84.               
  85.             SOCKADDR_IN cliAddr;  
  86.             SOCKET cliSock = -1;  
  87.             int nlen = sizeof(SOCKADDR);  
  88.             char buf[1024] = {0};  
  89.   
  90.   
  91.             FD_ZERO(&rfd);  
  92.             FD_SET(sockSvr,&rfd);  
  93.             nfds = select(1,&rfd,(fd_set*) 0,(fd_set*) 0,&timeout);  
  94.   
  95.             if(nfds==0)  
  96.             {  
  97.                 strMsg.Format(_T("请检查手持终端编号是否正确匹配,USB数据线是否正确连接!"));  
  98.                 dlg->m_pOutPutView->AddWarnInfo(strMsg,false);  
  99.                 dlg->m_btn_UsbInitTer.EnableWindow(TRUE);  
  100.                 dlg->m_bUsbinitingTer=false;   
  101.                 continue;  
  102.             }                 
  103.             else if(nfds>0)  
  104.             {  
  105.                 FD_CLR(sockSvr,&rfd);  
  106.                 //accept socket   
  107.                 cliSock = accept(sockSvr, (SOCKADDR*)&cliAddr, &nlen);  等待客户端请求并重新定义一个对应此次链接的socket   
  108.   
  109.   
  110.                 if (WSAEINTR == cliSock)             //判断sock是否创建成功   
  111.                 {  
  112.                     //char recvBuf[100];   
  113.                     /*printf("err code :%d",WSAGetLastError());//获取错误类型函数WSAGetLastError()*/  
  114.                     //return 0;   
  115.                 }  
  116.                 //发送数据   
  117.                 send(cliSock,dlg->m_initterminalbase,dlg->m_TerInitlen,0);  
  118.                 char recvBuf[100];  
  119.                 memset(recvBuf, 0, 100);  
  120.                 Sleep(1000);  
  121.                 //接收数据   
  122.                 recv(cliSock,recvBuf,100,0);  
  123.                 //closesocket(cliSock);   
  124.                 CString back=_T("");  
  125.                 back=(CString)recvBuf;  
  126.   
  127.   
  128.                 if (back!=_T("ok"))  
  129.                 {  
  130.                     nInitCount++;  
  131.                     if (nInitCount == 6)  
  132.                     {  
  133.                         nInitCount = 0;  
  134.                         strMsg.Format(_T("手持终端%s初始化失败,请检查手持终端USB是否正确连接,编号是否匹配!"),dlg->m_strTerInitName);  
  135.                         dlg->m_pOutPutView->AddWarnInfo(strMsg,false);  
  136.                         dlg->m_btn_UsbInitTer.EnableWindow(TRUE);  
  137.                         dlg->m_bUsbinitingTer=false;   
  138.                         continue;  
  139.                     }  
  140.                     else  
  141.                     {  
  142.                         strMsg.Format(_T("手持终端%s初始化失败,正在继续,请等待!"),dlg->m_strTerInitName);  
  143.                         dlg->m_pOutPutView->AddWarnInfo(strMsg,false);  
  144.                         Sleep(1000);              
  145.   
  146.                     }  
  147.   
  148.                 }  
  149.                 else  
  150.                 {  
  151.                     nInitCount = 0;  
  152.                     strMsg.Format(_T("手持终端%s初始化成功!"),dlg->m_strTerInitName);  
  153.                     dlg->m_pOutPutView->AddWarnInfo(strMsg,true);  
  154.                     dlg->m_btn_UsbInitTer.EnableWindow(TRUE);  
  155.                     dlg->m_bUsbinitingTer=false;   
  156.                     continue;  
  157.                 }     
  158.   
  159.             }  
  160.             else  
  161.             {  
  162.                 break;  
  163.   
  164.             }  
  165.               
  166.         }  
  167.           
  168.   
  169.     }  
  170.   
  171.     closesocket(sockSvr);                                                //关闭正在于客户端通信的服务端sock   
  172.     WSACleanup();//初始化关闭   
  173.     return 0;  
  174.   
  175.   
  176. }  
static int nInitCount = 0;
	//加载套接字socket(插座)
	WORD wVersionRequested;					//typedef unsigned short WORD;
	WSADATA wsaData;						//结构体  typedef struct WSAData   WSADATA    。typedef WSADATA FAR *LPWSADATA;
	int nReg = 0;							//错误函数的检测数值传递给nReg
	SOCKET sockSvr;							//typedef _W64 unsigned int 、、SOCKET;  
	SOCKADDR_IN addrSrv;
	int nErrCode = 0;
	int bExit = 0;
	unsigned long ul = -1;

	struct timeval timeout={2,0};
	fd_set rfd;
	int nfds;

	wVersionRequested = MAKEWORD(1, 1);		//请求.1版本socket

	nReg = WSAStartup(wVersionRequested,&wsaData);//初始化
	if (0 != nReg)
	{
		printf("err code :%d",WSAGetLastError());
		return 0;
	}
	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
		printf("VERSION DIFF");
		WSACleanup();
		return 0;
	}

	sockSvr = socket(AF_INET, SOCK_STREAM, 0); //socket(IN int af,IN int type,IN int protocol); SOCK_STREAM(使用TCP协议而不是UDP)创建socket
// 	nErrCode = ioctlsocket(sockSvr, FIONBIO, (unsigned long*)&ul);                 //设置套接字非阻塞模式
// 	if (nErrCode == SOCKET_ERROR)
// 	{
// 		//设置套接字非阻塞模式,失败处理
// 	}
	if (INVALID_SOCKET == sockSvr)             //判断sock是否创建成功
	{
		printf("err code :%d",WSAGetLastError());//获取错误类型函数WSAGetLastError()
		return 0;
	}

	//设定内部接口
	addrSrv.sin_family = AF_INET;										//启动协议
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);					//绑定地址
	addrSrv.sin_port = htons(26023);										//绑定端口

	nReg = bind(sockSvr, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));		//内部接口设定完成将整体绑定到服务器sockSvr
	if (SOCKET_ERROR == nReg)                                           //判断绑定是否成功
	{
		nErrCode = WSAGetLastError();
		if (nErrCode == WSAEADDRINUSE)									 //如果端口被占用
		{
			//printf("err code :%d,port is already used ",nErrCode);
		}
		else
		{

		}
			//printf("err code :%d",nErrCode);
		return 0;
	}

	//监听,准备接收
	listen(sockSvr, 5);									//最多同时监听个sock

	CString strMsg = _T("");
	while (TRUE)
	{
		if (WAIT_OBJECT_0 == WaitForSingleObject(dlg->m_hEventSocket,100))//结束押运箱
		{
			closesocket(sockSvr);                                                //关闭正在于客户端通信的服务端sock
			WSACleanup();//初始化关闭
			SetEvent(dlg->m_HEventExitSocket);
			return 0;
		}
		if (dlg->m_bUsbinitingTer)
		{
			if (nInitCount == 0)
			{
				strMsg.Format(_T("正在初始化%s手持终端,请等待..."),dlg->m_strTerInitName);
				dlg->m_pOutPutView->AddWarnInfo(strMsg,true);
			}
			
			SOCKADDR_IN cliAddr;
			SOCKET cliSock = -1;
			int nlen = sizeof(SOCKADDR);
			char buf[1024] = {0};


			FD_ZERO(&rfd);
			FD_SET(sockSvr,&rfd);
			nfds = select(1,&rfd,(fd_set*) 0,(fd_set*) 0,&timeout);

			if(nfds==0)
			{
				strMsg.Format(_T("请检查手持终端编号是否正确匹配,USB数据线是否正确连接!"));
				dlg->m_pOutPutView->AddWarnInfo(strMsg,false);
				dlg->m_btn_UsbInitTer.EnableWindow(TRUE);
				dlg->m_bUsbinitingTer=false;	
				continue;
			}				
			else if(nfds>0)
			{
				FD_CLR(sockSvr,&rfd);
				//accept socket
				cliSock = accept(sockSvr, (SOCKADDR*)&cliAddr, &nlen);	等待客户端请求并重新定义一个对应此次链接的socket


				if (WSAEINTR == cliSock)             //判断sock是否创建成功
				{
					//char recvBuf[100];
					/*printf("err code :%d",WSAGetLastError());//获取错误类型函数WSAGetLastError()*/
					//return 0;
				}
				//发送数据
				send(cliSock,dlg->m_initterminalbase,dlg->m_TerInitlen,0);
				char recvBuf[100];
				memset(recvBuf, 0, 100);
				Sleep(1000);
				//接收数据
				recv(cliSock,recvBuf,100,0);
				//closesocket(cliSock);
				CString back=_T("");
				back=(CString)recvBuf;


				if (back!=_T("ok"))
				{
					nInitCount++;
					if (nInitCount == 6)
					{
						nInitCount = 0;
						strMsg.Format(_T("手持终端%s初始化失败,请检查手持终端USB是否正确连接,编号是否匹配!"),dlg->m_strTerInitName);
						dlg->m_pOutPutView->AddWarnInfo(strMsg,false);
						dlg->m_btn_UsbInitTer.EnableWindow(TRUE);
						dlg->m_bUsbinitingTer=false;	
						continue;
					}
					else
					{
						strMsg.Format(_T("手持终端%s初始化失败,正在继续,请等待!"),dlg->m_strTerInitName);
						dlg->m_pOutPutView->AddWarnInfo(strMsg,false);
						Sleep(1000);			

					}

				}
				else
				{
					nInitCount = 0;
					strMsg.Format(_T("手持终端%s初始化成功!"),dlg->m_strTerInitName);
					dlg->m_pOutPutView->AddWarnInfo(strMsg,true);
					dlg->m_btn_UsbInitTer.EnableWindow(TRUE);
					dlg->m_bUsbinitingTer=false;	
					continue;
				}	

			}
			else
			{
				break;

			}
			
		}
		

	}

	closesocket(sockSvr);                                                //关闭正在于客户端通信的服务端sock
	WSACleanup();//初始化关闭
	return 0;


}



这里我是当用户PC的服务端点击按钮后发送数据,accept是原本是阻塞模式,这里用select超时模式,
  1. dlg->m_bUsbinitingTer  
dlg->m_bUsbinitingTer
用来判断用户点击了按钮让其变为ture。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值