foxmark.lib包含的文件:
ntdll.dll是NT操作系统重要的模块。
ntdll.dll是NT操作系统重要的模块。
ole32.dll是对象链接和嵌入相关模块
mutex:表现互斥现象的数据结构,也被当作二元信号灯。一个互斥基本上是一个多任务敏感的二元信号,它能用作同步多任务的行为,它常用作保护从中断来的临界段代码并且在共享同步使用的资源。
GetLogicalDriveStrings Get the number of removable partition
//Open list mutex
hMutex = OpenMutex (MUTEX_ALL_ACCESS, FALSE, "List Mutex");//为现有的一个已命名互斥体对象创建一个新句柄
WaitForSingleObject(hMutex,INFINITE);//线程中利用WaitForSingleObject来等待Event信号
CopyFile:用来copy文件的函数
WaitForSingleObject(hMutex,INFINITE);//线程中利用WaitForSingleObject来等待Event信号
程序的结构:
testbase类公共类 所有的模块基类;负责模块函数的声明:test(),GetModuleInfo(),DisplayWindow(),OutPutParameters(),UpsateTestResult(),SendErrorrMessage(),WriteLogHeader(),运行状态,
同时指定多个buff缓冲区,同时接收数据,切分数据
unsigned WINAPI Receiver(void *strIp)
{
SOCKET sockM;
struct sockaddr_in local,remote;
int McastPort = MUTICAST_PORT;
char McastIP[] = MUTICAST_IP;
int ret;
char Buffer[MUTICAST_BUFFER_LEN] = {0};
struct ip_mreq mreq;
int len = sizeof(struct sockaddr_in);
if ((sockM = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
{
printf("socket failed with: %d\n", WSAGetLastError());
return 2;
}
BOOL flag = TRUE;
ret = setsockopt(sockM, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(flag));
local.sin_family = AF_INET;
local.sin_port = htons(McastPort);
local.sin_addr.s_addr = inet_addr((char*)strIp);
if (bind(sockM, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
{
printf("bind failed with:: %d\n", WSAGetLastError());
closesocket(sockM);
return 3;
}
mreq.imr_multiaddr.s_addr = inet_addr(McastIP);
mreq.imr_interface.s_addr = inet_addr((char*)strIp);
if (setsockopt(sockM, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq)) == SOCKET_ERROR)
{
printf("setsocketopt(IP_ADD_MEMBERSHIP) failed with:: %d\n", WSAGetLastError());
closesocket(sockM);
return 4;
}
remote.sin_family = AF_INET;
remote.sin_port = htons(McastPort);
remote.sin_addr.s_addr = inet_addr(McastIP);
if ((ret = recvfrom(sockM, Buffer, MUTICAST_BUFFER_LEN, 0, (struct sockaddr*)&remote, &len)) == SOCKET_ERROR)
{
printf("recvfrom failed with: %d\n", WSAGetLastError());
closesocket(sockM);
return 5;
}
closesocket(sockM);
for (int i=0; i<MUTICAST_BUFFER_LEN; i++)
{
if (Buffer[i] != (char)i)
return 6;
}
return 0;
}
BOOL SocketInit()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
return FALSE;
}
return TRUE;
}
问题不在于此,如果对于阻塞线程,可以直接用send发送,除非下层缓冲耗尽了(这种情况如果不是网络另一端有问题,很少出现).但是如果自己在上层缓冲,则可能被缓冲数据由多个线程操作,操作的时候必然要互斥,这一去一来的消耗系统非常大,包就累积起来.我刚好做了这样的一个程序碰到这种情况了.
=================================================================
阻塞线程是什么?
在上层缓冲是有界定性的,也就是针对一个客户一个缓冲链,一客户最多也不过是两个线程(考虑到主线程可能产生主动发送,并且这种是完成端口设计框架当中所不建议的),而这种所谓的互斥也仅仅只是说为了更好的利用前一数据片断发送过程的间隔时间,这种系统消耗不会太大.
一开始的时候我也确实想过这个会带来相当的消耗,所以我就直接使用一个最原始的,也就是MS的IOCP ECHO Server例程来进行测试,结果我发现当中CPU的耗用同我所设计的差不蛮多,仅仅只是流量上面,确实比我的多几百KB/S(百兆局域网,传送速率为IO各5MB/s~5.8MB/s之间),而这个差额,主要还是在于我本身的设计缺陷所带来的.
目前我正打算重写,我设计的是工作线程可调节模式,也就是可以由主线程在一定范围内控制线程的数量,而这当中就存在一个问题,即当初我没有注意到当一个结程结束,会便得该线程投递的I/O操作被取消,这个目前倒是已经解决,另外一点就是我希望的是在同一个连接上面,收与发进行异步作业,也就是可以同步进行,那么就可能存在这样一个问题,当一个连接突然出现故障时,去删除相关的Context会出现意外,重新设计的思路就是不再直接删除,而是移至回收站,则清洁工结程进行处理,同时也考虑扫除部分长时间不工作的连接.
不过目前我还没有测试出来,这个同一连接上面的异步I/O的可行性.
需求:通socket编程(一)的需求
该实例中,客户端可能会有多个,服务器的处理器也会有多个,该情形类似于消费者在超市结账的过程,
假设固定有5个收银员,而消费者不确定:
如果开始没有消费者来结账,那么所有的收银员都处于等待状态;
如果有一个消费者来结账,那么随即会有一个收银员来处理,其他的收银员仍处于等待状态;
如果有大于一个小于6个的消费者来结账,那么收银员都会随即进行处理;
如果有大于5个的消费者在等待,就需要排队了(这也就是要说的连接池即客户端的请求链接放置的地方,把客户请求放在这个池子里)