There should be no more than one reason to change the class。
任何类都不应该从具体类派生。
朋友类:
出现在成员变量、方法的输入输出参数中的类称为朋友类
IOCP
1 手把手教你玩转网络编程模型之完成例程(Completion Routine)篇(上)
http://blog.csdn.net/piggyxp/article/details/3910726
重叠I/O:
简单来讲就是Windows系统内部管理I/O的一种方式,核心就是调用的ReadFile和WriteFile函数,在制定设备上执行I/O操作,不光是可用于网络通信,也可以用于其他需要的地方。
完成端口会充分利用Windows内核来进行I/O的调度,是用于C/S通信模式中性能最好的网络通信模型,没有之一;甚至连和它性能接近的通信模型都没有。
WSARecv函数还有另外一个作用,如果客户端断开连接了,WSARecv会收到一个0字节的返回,我们可以根据这个释放连接对象。如果客户端直接拔网线,WSARecv是检测不到,这是我们要根据超时来检测。
提高服务器性能的方法:
优化锁的调用次数
IOCP性能优化主要是集中在每个处理接收数据和发送数据的对象锁,如果能降低锁的调用次数和提高锁的效率,对IOCP的整理效率和吞吐量都非常有帮助。有很多开发人员在优化IOCP的时候,对于如何提高锁的效率,有使用原子操作来加锁,这样做的效率比较调用Windows的锁效率,因而吞吐率也更高。
在广域网的时候,优化锁的调用次数对性能提升比较明显,尤其是小数据量的交互响应时间,能降低一半。吞吐量的提升在局域网测试的时候,可以把千兆网卡占完,达到125MB/S(千兆网卡是1Gb/S / 8 = 125MB/S,网卡的工业标准是使用bit)。
WSASend,WSARead, PostQueuedCompletionStatus三个函数都会传递LPOVERLAPPED lpOverlapped,其实这三个参数是可以自定义的,只要记得在GetQueuedCompletionStatus函数返回时,解析成对应的格式就可以了。
问题:
1. 通常情况下,一次发送的数据长度是多少?
2. 如果两次重复发送的数据比较短,间隔时间也短,系统会不会把两次投递的数据合在一起,一次性投递出去?
多线程:
1.假设,有一个事件对象是手动的(CreateEvent(NULL,TRUE,FALSE,NULL),有5个线程在等待信号(WaiforSingleObject),则当调用SetEvent时,5个线程会同时收到信号,得到信号之后的代码执行顺序是随机的。
问题:得到信号之后的代码执行顺序,取决于线程得到时间片的顺序吗?。
2.假设,有一个事件对象是自动(CreateEvent(NULL,FALSE,FALSE,NULL),有5个线程在等待信号(WaiforSingleObject),则当调用SetEvent时,只有一个线程会得到信号,得到信号的这个线程也是随机的。
问题:得到执行的这个线程,也是取决于哪个线程先得到时间片吗?
是否可以认为:
1. 当线程调用WaiforSingleObject等函数时,其实操作系统也会给他分配时间片,只是如果这个信号一直是无信号状态,我们就看不到线程的执行?
2. 当信号变成有信号时,同时等待的多个线程,哪个先得到执行的时间片就得到了信号,得到继续执行的权利?
测试代码如下,执行顺序请在状态下查看“输出”窗口,查看线程退出码,可以知道是哪个线程退出了,你可能需要新建一个对话框工程,并添加两个按钮:
long nCnt = 0;
HANDLE hEvent = NULL;
DWORD ThreadProc(LPARAM lp)
{
InterlockedIncrement(&nCnt);
int nRet = nCnt;
TRACE("wait: %d\n", nRet);
WaitForSingleObject(hEvent, INFINITE);
//TRACE("end : %d\n", nRet);
return nRet;
}
void CTestMfcDlg::OnBnClickedButton1()
{
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
for (int i=0; i<25; i++)
{
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, 0, 0, 0);
}
}
void CTestMfcDlg::OnBnClickedButton2()
{
SetEvent(hEvent);
}
1. initialize Winsock (WSAStartup)
2. create the I/O Completion Port (CreateIoCompletionPort)
3. create the listening socket (listen)
4. associate the listening socket with the IOCP (CreateIoCompletionPort)
5. bind the listening socket (bind)
6. start listening (listen)
7. create a pointer to the AcceptEx function (!)
8. start accepting a new connection (asynchronous AcceptEx)
// the completion status for AcceptEx will be reported through
// the listen IOCP completion status (see step 4)
9. wait for a completion port status (GetQueuedCompletionStatus)
9.1if the completion status is for an accept (an AcceptEx has completed)
9.1.1"update the context" of the new socket (whatever that is...)
9.1.2 associate the new socket with the completion port
9.1.3 start reading from the new socket (asynchronous WSARecv)
9.1.4 start accepting another connection (asynchronous AcceptEx)
9.1.5 go to step 9
9.2if the completion status is for a read (a WSARecv has completed)
9.2.1 start writing to the socket through which the data arrived,
echoing back the data (asynchronous WSASend)
9.2.2 go to step 9
9.3if the completion status is for a write (a WSASend has completed)
9.3.1 start reading again from the socket that was used to send the data
(asynchronous WSARecv)
9.3.2 go to step 9
TCPIP
ARP:地址解析协议
RARP :逆地址解析协议
InterNIC: Internet Network Information Center
octet: 字节
R F C(Request for Comment)
持环回接口( Loopback Interface
I P在首部中存入一个长度为
8 b i t的数值,称作协议域。1表示为I C M P协议, 2表示为I G M P协议, 6表示为T C P协议, 1 7表示为U D P协议。
T C P和U D P都用一个1 6 b i t的端口号来表示不同的应用程序。T C P和U D P把源端口号和目的端口号分别存入报文首部中
T C P / I P实现来说, F T P服务
器的T C P端口号都是2 1,每个Te l n e t服务器的T C P端口号都是2 3,每个T F T P (简单文件传送协
议)服务器的U D P端口号都是6 9
以太网和8 0 2 . 3对数据帧的长度都有一个限制,其最大值分别是
1 5 0 0和1 4 9 2字节