写了个UDP传输文件的东东.(经丢包测试)
先扔个头文件上来MARK下
Code
1
#pragma once
2
#include "Net.h"
3![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//********************************************************************
4
created: 2009/04/07
5
created: 7:4:2009 17:10
6
filename: f:\work\MyProject\myiu\IU\include\UDPFilesStrategy.h
7
file path: f:\work\MyProject\myiu\IU\include
8
file base: UDPFilesStrategy
9
file ext: h
10
author: kevin meng
11
12
purpose: UDP传输文件的上层策略
13
*********************************************************************/
14![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
15![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**///
16
//加载Files.lib
17
#pragma comment (lib,"../bin/Files.lib")
18
#include "Files.h"
19![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**///
20
//加载临界锁
21
#include "CriticalSectionLock.h"
22![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//********************************************************************
23
purpose: 滑动窗口 UDP 传送文件
24
只使用了简单的滑动窗口机制
25
实现:
26
1.固定的窗口大小
27
2.固定的传输速率
28![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
29
没有实现:
30
1.拥塞窗口机制
31
2.RTT计算
32
3.等等
33
该类的App层:
34
*********************************************************************/
35![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
extern "C"
{
36![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
37
//上层APP控制,必须继承的类(以该类虚函数为接口)
38![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
class NET_API CUDPFilesStrategy_App
{
39
public:
40![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
CUDPFilesStrategy_App()
{};
41![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
virtual ~CUDPFilesStrategy_App()
{};
42
public:
43
//由CUDPFilesStrategy 调用继承CUDPFilesStrategy_App 并实现DoOnFileSize 的函数 传递文件大小
44
virtual void DoOnFileSize(uint nFileSize) = 0;
45
46
//由CUDPFilesStrategy 调用继承CUDPFilesStrategy_App 并实现DoOnTransferState 的函数 说明现在传输的状态
47
//************************************
48
// Method: DoOnTransferState
49
// FullName: CUDPFilesStrategy_App::DoOnTransferState
50
// Access: virtual public
51
// Returns: void
52
// Qualifier:
53
// Parameter: ushort nPercent (范围0-100)该参数为100时说明传输完毕
54
// Parameter: uint nSpeed 传输速度(kb/s)
55
// Parameter: uint nComplete 传输完成数量
56
// Parameter: uint nSpare 传输剩余数量
57
// Parameter: uint nTagID 标示传输文件的ID
58
//************************************
59
virtual void DoOnTransferState(ushort nPercent,uint nSpeed,uint nComplete,uint nSpare,uint nTagID = 0) = 0;
60
61
//由CUDPFilesStrategy 调用继承CUDPFilesStrategy_App 并实现DoOnSend 的函数 发送数据
62![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
virtual void DoOnSend(const char* pBuf,uint nBufSize,uint nTagID = 0/**//*标示传输文件的ID*/) = 0;
63
protected:
64
private:
65
};
66![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
67
class NET_API CUDPFilesStrategy
68![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
69
public:
70
CUDPFilesStrategy(void);
71
virtual ~CUDPFilesStrategy(void);
72
protected:
73
//判断该段是否在窗口内
74
inline bool _InWindows(uint nPosition);
75
void _SetFileSize(uint nFileSize);
76
77
78
//常量
79![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
typedef enum _E
{
80
e_WindSize = 10,//窗口大小
81
e_SendSpeed = 100,//发送速度PACK/S (每秒100KB)
82
e_OnceSendSize = 1024//一次发送最大字节数(数据)
83
};
84
//消息ID
85![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
typedef enum _E_MSG_ID
{
86
e_SendData = 10000,//发送数据的ID
87
e_RecvAck = 10001//发送ACK的ID
88
};
89![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//////
90
//消息结构体SR: SEND->RECV
91![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
typedef struct tag_MSG_SR_DATA
{
92
uint nMSGID;//_E_MSG_ID
93
uint nSeq;//序号
94
uint nSize;//数据区实际长度
95
char szBuf[e_OnceSendSize];
96![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
tag_MSG_SR_DATA(void)
{
97
nMSGID = e_SendData;
98
}
99
};
100
//#
101![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
102![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
103![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**/////
104
//消息结构体RS: RECV->SEND
105![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
typedef struct tag_MSG_RS_ACK
{
106
uint nMSGID;//_E_MSG_ID
107
uint nSeq;//序号
108![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
tag_MSG_RS_ACK(void)
{
109
nMSGID = e_RecvAck;
110
}
111
};
112
//#
113![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
114![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**/////
115
//线程相关
116
HANDLE m_hThread;
117
bool m_bThreadRun;
118
//#
119
120![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**////
121
//当前窗口位置相关
122
uint m_nCurrentPosition;//当前窗口起始位置1,2,3,4
从1开始
123
CCriticalSectionLock m_iCurrentPositionLock;
124
inline uint _GetCurrentPosition();
125
inline void _SetCurrentPosition(uint val);
126
//#
127![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
128![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**////
129
//文件操作,属性
130
uint m_nFileBlock;//文件块数(文件按照一次发送大小最后计算出来的块数量)(不会改变)
131
CCriticalSectionLock m_iFileBlockLock;
132
inline uint _GetFileBlock();
133
inline void _SetFileBlock(uint val);
134
CFiles m_iCFiles;//操作文件的类
135
uint m_nFileID;//传送或接收文件的ID;(不会改变)
136
uint m_nFileSize;//文件长度(不会改变)
137
138
//#
139![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
140
141
CUDPFilesStrategy_App* m_piCUDPFilesStrategy_App;//上层APP的回调指针
142![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
143
uint m_nSleekWindows;//滑动窗口大小
144
uint m_nCongestionWindows;//拥塞窗口大小
145![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
146
private:
147![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
148
};
149![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
150![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
151
class NET_API CUDPFilesStrategySend : public CUDPFilesStrategy
152![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
153
public:
154
CUDPFilesStrategySend();
155
virtual ~CUDPFilesStrategySend();
156
public:
157
//************************************
158
// Method: BeginSendFile
159
// FullName: CFilesUdp::BeginSendFile
160
// Access: public
161
// Returns: BOOL
162
// Qualifier:
163
// Parameter: const char * pszFilePath 文件路径
164
// Parameter: CFilesUdpApp * pCFilesUdpApp 上层调动层的指针
165
//************************************
166
BOOL BeginSendFile(const char* pszFilePath,CUDPFilesStrategy_App* pCUDPFilesStrategy_App,uint nID);
167
void EndSendFile(void);
168![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
169
//由APP层调用的RECV(),APP层收到
170
inline void RecvAck(const char* pBuf,uint nBufSize);
171
protected:
172
private:
173![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//
174
//发送线程相关
175
static unsigned __stdcall __ThreadSend(void* pData);
176
void __ThreadSendFn(void);
177
//#
178![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
179
//发送数据前组包
180
//************************************
181
// Method: __CompositePacket
182
// FullName: CUDPFilesStrategySend::__CompositePacket
183
// Access: private
184
// Returns: uint
185
// Qualifier:
186
// Parameter: IN const char * pBuf 传入数据
187
// Parameter: uint nSize 传入数据大小
188
// Parameter: OUT char * pSendBuf 组包后的数据
189
// Parameter: uint nCurrentPosition 当前块ID
190
//************************************
191
inline uint __CompositePacket(IN const char* pBuf,uint nSize,OUT char* pSendBuf,uint nCurrentPosition);
192
};
193![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
194![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
195
class NET_API CUDPFilesStrategyRecv : public CUDPFilesStrategy
196![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
197
public:
198
CUDPFilesStrategyRecv();
199
virtual ~CUDPFilesStrategyRecv();
200
public:
201
BOOL BeginRecvFile(const char* pszFilePath,CUDPFilesStrategy_App* pCUDPFilesStrategy_App,uint nID);
202
void EndRecvFile(void);
203
//由APP层调用的RECV
204
void RecvData(const char* pBuf,uint nBufSize);
205![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
206
protected:
207
private:
208
static unsigned __stdcall __ThreadDelaySendACK(void* pData);//延迟发送ACK
209
void __ThreadDelaySendACKFn(void);
210![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
211
//解包
212
// uint __ParsePacket(const char* pBuf,uint nSize,char* pSendBuf);
213
};
214
#include "UDPFilesStrategy.inl"
215
}//extern "C"
转载于:https://www.cnblogs.com/kevinmeng/archive/2009/04/26/1443942.html