18,356
社区成员
发帖
与我相关
我的任务
分享
int len_head =sizeof(modbus->stx)+sizeof(modbus->address)+sizeof(modbus->command)+sizeof(modbus->len);
int len_data = modbus->getDataLength();
int len_tail = sizeof(modbus->fcs);
int length = len_head+len_data+len_tail;
if(length > MAX_UDP_PACKET_SIZE)
return X_UDP_TOOMUCH_DATA;
CHAR* pBuf = (CHAR*)_alloca(length);
memcpy(pBuf,modbus,len_head);
if(len_data>0)
memcpy(pBuf+len_head,modbus->data,len_data);
memcpy(pBuf+len_head+len_data,modbus->fcs,len_tail);
int total = 0;
while(total < length)
{
int sended = sendto(g_socket,pBuf+total,length-total,0,(sockaddr*)addr,sizeof(sockaddr));
if(sended <= 0)
break;
total+=sended;
}
return total==length?X_UDP_OK:X_UDP_WRITE_FAILED;
LPSOCKET_REQUEST removeFirstRequest()
{
EnterCriticalSection( &g_cs );
LPSOCKET_REQUEST pRequest = NULL;
__try
{
if( true == g_listRequests.empty())
__leave;
pRequest = g_listRequests.front();
g_listRequests.pop_front();
}
__finally
{
LeaveCriticalSection( &g_cs );
}
return pRequest;
}
typedef std::list<LPDEVICE_REQUEST> LISTREQUEST;
static LISTREQUEST g_listRequests;
extern "C" BYTE XUDPMANAGER_API __stdcall UdpInsertRequest2(LPSOCKET_REQUEST request)
{
EnterCriticalSection( &g_cs );
__try
{
g_listRequests.push_back(request);
}
__finally
{
LeaveCriticalSection( &g_cs );
}
if(g_eventWork)
SetEvent(g_eventWork);
return X_UDP_OK;
}
int writeModbusPackage(sockaddr_in *addr,LPMODBUS_PACKAGE modbus)
{
// 一次性发送,接收端使用ReadFile(...overlapped)接收时会报错ERROR_MORE_DATA
static CHAR prefix[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00};
sendto(g_socket,prefix,sizeof(prefix),0,(sockaddr*)addr,sizeof(sockaddr));
//////////////////////////////////////////////////////////////////////////
//1.3 版后去掉etx段
int len_head =sizeof(modbus->stx)+sizeof(modbus->address)+sizeof(modbus->command)+sizeof(modbus->len);
int len_data = modbus->getDataLength();
int len_tail = sizeof(modbus->fcs);
int length = len_head+len_data+len_tail;
if(length > MAX_UDP_PACKET_SIZE)
return X_UDP_TOOMUCH_DATA;
CHAR* pBuf = (CHAR*)_alloca(length);
memcpy(pBuf,modbus,len_head);
if(len_data>0)
memcpy(pBuf+len_head,modbus->data,len_data);
memcpy(pBuf+len_head+len_data,modbus->fcs,len_tail);
int total = 0;
while(total < length)
{
int sended = sendto(g_socket,pBuf+total,length-total,0,(sockaddr*)addr,sizeof(sockaddr));
if(sended <= 0)
break;
total+=sended;
}
return total==length?X_UDP_OK:X_UDP_WRITE_FAILED;
}
unsigned int __stdcall threadProc(LPVOID)
{
traceline(TEXT("udp worker thread started.\n"));
static sockaddr_in addr;
memset(addr.sin_zero,0,sizeof(addr.sin_zero));
addr.sin_family=AF_INET;
HANDLE handles[2] = {g_eventExit,g_eventWork};
while(true)
{
DWORD result = WaitForMultipleObjects(2,handles,FALSE,INFINITE);
if(result == WAIT_OBJECT_0)
break;
else if(result == WAIT_OBJECT_0+1)
{
while(!g_listRequests.empty())
{
LPSOCKET_REQUEST request = removeFirstRequest();
if(!request)
break;
LPDEVICE_REQUEST devReq = request->pRequest;
MODBUS_PACKAGE modbus(devReq);
addr.sin_addr.s_addr=request->ip;
addr.sin_port=htons(request->port);
if( writeModbusPackage(&addr,&modbus) == X_UDP_OK )
#ifdef _UNICODE
traceline(L"UDP write ip:%S port:%d command:0x%02X address:0x%04X content:%S\n",inet_ntoa(addr.sin_addr),request->port,devReq->command,devReq->address,(devReq->pDetail&&devReq->pDetail[0])?devReq->pDetail:"NULL");
#else
traceline("UDP write ip:%s port:%d command:0x%02X address:0x%04X content:%S\n",inet_ntoa(addr.sin_addr),request->port,devReq->command,devReq->address,(devReq->pDetail&&devReq->pDetail[0])?devReq->pDetail:"NULL");
#endif
else
traceline(TEXT("UDP write request failed.\n"));
delete request;
}
}
}
traceline(TEXT("udp worker thread aborted.\n"));
return 0;
}