初级会员

- 积分
- 131
- 金钱
- 131
- 注册时间
- 2018-1-18
- 在线时间
- 18 小时
|
1金钱
本帖最后由 szttg 于 2020-11-11 18:47 编辑
大家好,我用VS2015给PC机写了一个给F407发送升级文件的工程,使用的是UDP协议,设备收到每块数据后,都会给上位机发确认包,包含了块号。
在使用过程中发现,经常会出现发送一部分数据后,上位机收不到确认包的问题,文件的大小为600K左右。
下面是创建线程的函数SendFile() 和发送数据、接收确认包的两个线程函数,请教大家问题出在什么地方。
万分感谢!!!
void CAsyncSockChatDlg::SendFile(u8 devIndex, u32 DestIP, TransferDataType updateType)
{
memset(&sfp[devIndex], 0, sizeof(SendFileParaType));
if (MCU == updateType)
{
memcpy(sfp[devIndex].filename, m_mcu_file.GetBuffer(), m_mcu_file.GetLength());
sfp[devIndex].fileblocks = m_mcu_fileblocks;
}
else if (FPGA == updateType)
{
memcpy(sfp[devIndex].filename, m_fpga_file.GetBuffer(), m_fpga_file.GetLength());
sfp[devIndex].fileblocks = m_fpga_fileblocks;
}
sfp[devIndex].hWnd = m_hWnd;
sfp[devIndex].UpdateType = updateType; // 更新类型
sfp[devIndex].s = socket(AF_INET, SOCK_DGRAM, 0);
if (INVALID_SOCKET == sfp[devIndex].s)
{
return;
}
// 设备地址
sfp[devIndex].sendAdd.sin_addr.S_un.S_addr = DestIP;
sfp[devIndex].sendAdd.sin_family = AF_INET;
sfp[devIndex].sendAdd.sin_port = htons(DEVRCV_PORT);
// 接收确认数据地址
SOCKADDR_IN recvAdd;
recvAdd.sin_addr.S_un.S_addr = m_local_ip.GetItemData(m_local_ip.GetCurSel());
recvAdd.sin_family = AF_INET;
recvAdd.sin_port = htons(LOCAL_PORT++);
bind(sfp[devIndex].s, (SOCKADDR*)&recvAdd, sizeof(SOCKADDR));
sfp[devIndex].hSendEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
CreateThread(0,0, Thread_Send, &sfp[devIndex], 0,0);
CreateThread(0, 0, Thread_Recv, &sfp[devIndex], 0, 0);
}
// 文件发送线程函数
u16 LOCAL_PORT = 9000;
DWORD WINAPI Thread_Send(LPVOID p)
{
SendFileParaType* pSFP = (SendFileParaType*)p;
u16 dataBytes = 0;
u16 sendBlock = 0;
int ReadBytes = 0, SentBytes = 0;
CString str;
CFile file;
CFileException ex;
BYTE sBuf[272] = { 0XAA,
0x01, 0x07, // length
0x00, 0x81, // MCU 0x81 FPGA 0x80
0x00, 0xA1, // A1 : Data
0x00, 0x00 // block number
};
sBuf[4] = pSFP->UpdateType;
if (!file.Open(pSFP->filename, CFile::shareDenyNone, &ex))
{
CString str; str.Format("Open file fail: %s", pSFP->filename);
AfxMessageBox(str);
return -1;
}
do
{
WaitForSingleObject(pSFP->hSendEvent, INFINITE);
ReadBytes = file.Read(&sBuf[9], 256);
if (ReadBytes > 0)
{
dataBytes = 9 + ReadBytes;
sBuf[1] = dataBytes >> 8 & 0xFF;
sBuf[2] = dataBytes & 0xFF;
// block number
sBuf[7] = sendBlock >> 8 & 0xFF;
sBuf[8] = sendBlock & 0xFF;
// checkSum
sBuf[dataBytes] = CheckSum(sBuf, dataBytes);
SentBytes = sendto(pSFP->s, (char*)sBuf, 1 + dataBytes, 0, (SOCKADDR*)&pSFP->sendAdd, sizeof(SOCKADDR));
sendBlock++;
//PostMessage(pSFP->hWnd, UM_SENDFILE_BLOCKS, pSFP->UpdateType << 24 | sendBlock, pSFP->sendAdd.sin_addr.S_un.S_addr);
}
} while (ReadBytes);
file.Close();
}
// 接收确认包线程函数
DWORD WINAPI Thread_Recv(LPVOID p)
{
SendFileParaType* pSFP = (SendFileParaType*)p;
char recvBuf[16];
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
int rcvLen = 0;
u16 rcvBlock = 0;
do
{
rcvLen = recvfrom(pSFP->s, recvBuf, 100, 0, (SOCKADDR*)&addrClient, &len);
rcvBlock = (recvBuf[7] & 0xFF) * 256 + (recvBuf[8] & 0xFF);
PostMessage(pSFP->hWnd, UM_SENDFILE_BLOCKS, pSFP->UpdateType << 24 | (rcvBlock + 1), addrClient.sin_addr.S_un.S_addr);
SetEvent(pSFP->hSendEvent);
} while (rcvBlock < (pSFP->fileblocks-1));
closesocket(pSFP->s);
CloseHandle(pSFP->hSendEvent);
// 给窗口发送消息
if (rcvBlock == (pSFP->fileblocks - 1))
{
SendMessage(pSFP->hWnd, UM_SENDFILE_OK, pSFP->UpdateType << 24 | 0, addrClient.sin_addr.S_un.S_addr);
return 0;
}
else
{
SendMessage(pSFP->hWnd, UM_SENDFILE_FAIL, pSFP->UpdateType << 24 | 0, addrClient.sin_addr.S_un.S_addr);
return -1;
}
}
|
|