青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 298  文章 - 377  trackbacks - 0
<2007年7月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

常用鏈接

留言簿(34)

隨筆分類

隨筆檔案

文章檔案

相冊

收藏夾

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

Introduction

I have been writing server applications on Windows server platforms for quite sometime. We all know that I/O completion port is one of the nicest things available for writing server applications (or even in clients where you can apply Worker-Boss pattern). There are tons of articles and samples to show how I/O completion port can be used with TCP/IP. Surprisingly enough, I did not find any source code examples to demonstrate the use of I/O completion ports with UDP.

To spice up things a little, I took the multicast topic to demonstrate the code. Most of the multicast code is borrowed from Mr. Bob Quinn's article.

This sample consists of two projects (Client and Server). In order to test this application as it is, routers in your network should be enabled for multicast routing. If not, modify samples appropriately to act just UDP server and client.

Since there is so much written about I/O completion port and multicast, I won't go into all the details in this article.

Server application design and implementation is an art. You can put so many bells and whistles. Typical server application should have the following:

  1. Object Pooling

    If any of the object is to be created and destroyed often, consider making a pool of such objects. Typical example would be your sockets, user context objects, database connections.

  2. Ease of configuration

    Do not hardcode configuration information in the code. Try to use XML configuration files. Let the application read these vales during the startup. Typical examples would be, IP address of other servers, Oracle TNS names, user ids and passwords (!!!), number of worker threads, email addresses etc.

    Besides, there should be some mechanism to change these parameters while the server is running.

  3. Monitoring and logging

    Since most of these servers will be running somewhere in the data center, it is nice to have a small component sitting in your server application which will send log messages to central server from where you multicast those messages to other client applications. Make sure you have very good filtering mechanism so that you can control the number of messages being logged during the run time.

  4. Error handling

    Your servers have to be running nonstop (four nines most of the time). That means you should have proper error handling mechanism. Make use of SEH in a responsible manner. Besides keep track of number of TCP connections (using SNMP) and CPU usage, memory usage (Microsoft provides a library by which you can query all these parameters from within your program).

  5. Thread Synchronization

    Make sure you thread protects the shared data.

  6. Load balancing.

    You can not serve infinite number of clients from one server box. Always keep the 'scale-out' factor in mind. Do proper capacity planning to quantify your server hardware requirement. 80-20 rule is quite effective.

Source Code

Collapse
//NOTE
// 
//This code taken from Mr. Bob Quinn's article 
//titled 'Internet Multicasting'
//published in Dr. Dobb's Journal dated Oct 1997
//I have modified the original code to illustrate 
//the use I/O completion ports with UDP.
//If you have any comments email me : shapall@hotmail.com
#include "StdAfx.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include "Stdio.h"
#define BUFSIZE 1024 //max size of incoming data buffer
#define MAXADDRSTR 16
#define DEFAULT_GROUP_ADDRESS "239.254.1.2"
#define DEFAULT_PORT 7125 
LONG nCount = 0;
HANDLE g_hCompletionPort;
DWORD WINAPI WorkerThread( LPVOID WorkContext );
BOOL HandleIncomingData( UCHAR* pBuf);
BOOL CreateNetConnections( VOID );
BOOL CreateWorkers( UINT );
void InitWinsock2();
void UnInitWinsock2();
HANDLE g_hReadEvent;
SOCKET g_hSocket;
UCHAR achInBuf [BUFSIZE];
char achMCAddr[MAXADDRSTR] = DEFAULT_GROUP_ADDRESS;
u_short nPort = DEFAULT_PORT;
OVERLAPPED Overlapped;
//-----------------------------------------------------------------
void InitWinsock2()
{
WSADATA data;
WORD version;
int ret = 0;
version = (MAKEWORD(2, 2));
ret = WSAStartup(version, &data);
if (ret != 0)
{
ret = WSAGetLastError();
if (ret == WSANOTINITIALISED)
{
printf("not initialised");
}
}
}
//-----------------------------------------------------------------
void UnInitWinsock2()
{
WSACleanup();
}
//-----------------------------------------------------------------
BOOL CreateNetConnections (void)
{
DWORD nbytes;
BOOL b;
BOOL fFlag = TRUE;
int nRet=0;
SOCKADDR_IN stLclAddr;
struct ip_mreq stMreq; // Multicast interface structure  
// Get a datagram socket  
g_hSocket = socket(AF_INET, SOCK_DGRAM,0);
if (g_hSocket == INVALID_SOCKET)
{
printf ("socket() failed, Err: %d\n", WSAGetLastError());
return FALSE;
}
nRet = setsockopt(g_hSocket,SOL_SOCKET,
SO_REUSEADDR, (char *)&fFlag, sizeof(fFlag));
if (nRet == SOCKET_ERROR)
{
printf ("setsockopt() SO_REUSEADDR failed,
Err: %d\n",WSAGetLastError());
}
// Name the socket (assign the local port number to receive on)  
stLclAddr.sin_family = AF_INET;
stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY);
stLclAddr.sin_port = htons(nPort);
nRet = bind(g_hSocket,(struct sockaddr*) &stLclAddr,sizeof(stLclAddr));
if (nRet == SOCKET_ERROR)
{
printf ("bind() port: %d failed, Err: %d\n",
nPort,WSAGetLastError());
}
// Join the multicast group so we can receive from it  
stMreq.imr_multiaddr.s_addr = inet_addr(achMCAddr);
stMreq.imr_interface.s_addr = INADDR_ANY;
nRet = setsockopt(g_hSocket,IPPROTO_IP,
IP_ADD_MEMBERSHIP,(char *)&stMreq,sizeof(stMreq));
if (nRet == SOCKET_ERROR)
{
printf("setsockopt() IP_ADD_MEMBERSHIP address %s failed,
Err: %d\n",achMCAddr,
WSAGetLastError());
}
//
//note the 10 says how many concurrent cpu bound threads to allow thru 
//this should be tunable based on the requests. CPU bound requests will 
// really really honor this. 
// 
g_hCompletionPort = CreateIoCompletionPort (INVALID_HANDLE_VALUE,
NULL,0,3);
if (!g_hCompletionPort)
{
fprintf (stdout, "g_hCompletionPort Create Failed\n");
return FALSE;
}
//Associate this socket to this I/O completion port 
CreateIoCompletionPort((HANDLE)g_hSocket,g_hCompletionPort,
(DWORD)g_hSocket,3);
//
// Start off an asynchronous read on the socket.  
//  
Overlapped.hEvent = g_hReadEvent;
Overlapped.Internal = 0;
Overlapped.InternalHigh = 0;
Overlapped.Offset = 0;
Overlapped.OffsetHigh = 0;
b = ReadFile ((HANDLE)g_hSocket,&achInBuf,
sizeof(achInBuf),&nbytes,&Overlapped);
if (!b && GetLastError () != ERROR_IO_PENDING)
{
fprintf (stdout, "ReadFile Failed\n");
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------
BOOL CreateWorkers (UINT dwNumberOfWorkers)
{
DWORD ThreadId;
HANDLE ThreadHandle;
DWORD i;
for (i = 0; i < dwNumberOfWorkers; i++)
{
ThreadHandle = CreateThread (NULL,0,
WorkerThread,NULL,0,&ThreadId);
if (!ThreadHandle)
{
fprintf (stdout, "Create Worker Thread Failed\n");
return FALSE;
}
CloseHandle (ThreadHandle);
}
return TRUE;
}
//-----------------------------------------------------------------
DWORD WINAPI WorkerThread (LPVOID WorkContext)
{
DWORD nSocket;
BOOL b;
OVERLAPPED ovl;
LPOVERLAPPED lpo=&ovl;
DWORD nBytesRead=0;
DWORD nBytesToBeRead;
UCHAR ReadBuffer[BUFSIZE];
LPVOID lpMsgBuf;
memset(&ReadBuffer,0,BUFSIZE);
for (;;)
{
b = GetQueuedCompletionStatus(g_hCompletionPort,
&nBytesToBeRead,&nSocket,&lpo,INFINITE);
if (b || lpo)
{
if (b)
{
// 
// Determine how long a response was desired by the client. 
// 
OVERLAPPED ol;
ol.hEvent = g_hReadEvent;
ol.Offset = 0;
ol.OffsetHigh = 0;
b = ReadFile ((HANDLE)nSocket,&ReadBuffer,
nBytesToBeRead,&nBytesRead,&ol);
if (!b )
{
DWORD dwErrCode = GetLastError();
if( dwErrCode != ERROR_IO_PENDING )
{
// something has gone wrong here... 
printf("Something has gone
wrong:Error code - %d\n",dwErrCode );
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dwErrCode,
MAKELANGID(LANG_NEUTRAL,
SUBLANG_DEFAULT),// Default language
(LPTSTR) &lpMsgBuf, 0, NULL);
OutputDebugString((LPCTSTR)lpMsgBuf);
//Free the buffer. 
LocalFree(lpMsgBuf );
}
else if( dwErrCode == ERROR_IO_PENDING )
{
// I had to do this for my UDP sample 
//Never did for my TCP servers 
WaitForSingleObject(ol.hEvent,INFINITE);
HandleIncomingData(ReadBuffer);
}
}
else
{
HandleIncomingData(ReadBuffer);
}
continue;
}
else
{
fprintf (stdout, "WorkThread Wait Failed\n");
//exit (1); 
}
}
return 1;
}
}
//-----------------------------------------------------------------
BOOL HandleIncomingData( UCHAR* pBuf)
{
InterlockedIncrement(&nCount);
SYSTEMTIME *lpstSysTime;
lpstSysTime = (SYSTEMTIME *)(pBuf);
printf("[%d]UTC Time %02d:%02d:%02d:%03d on %02d-%02d-%d \n",nCount,
lpstSysTime->wHour, lpstSysTime->wMinute,
lpstSysTime->wSecond, lpstSysTime->wMilliseconds,
lpstSysTime->wMonth, lpstSysTime->wDay, lpstSysTime->wYear);
memset(&pBuf,0,BUFSIZE);
//just making sure that i am not showing stale data 
return TRUE;
}
//-----------------------------------------------------------------
main ()
{
//You can modify your program to take some arguments for port number 
//and multicast group address here 
printf("\n***************************************\n");
printf("Group IP address: %s\n",achMCAddr);
printf("Port number : %d\n",nPort);
printf("\n***************************************\n");
//Initialize winsock 2 
InitWinsock2();
//We want to keep the main thread running 
HANDLE hWait2Exit = CreateEvent(NULL,FALSE,TRUE,"MCLIENT");
ResetEvent(hWait2Exit );
//This OVERLAPPED event 
g_hReadEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
// 
// try to get timing more accurate... Avoid context 
// switch that could occur when threads are released 
// 
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
if (!CreateNetConnections ())
{
printf("Error condition @ CreateNetConnections , exiting\n");
return 1;
}
if (!CreateWorkers (5))
{
printf("Error condition @CreateWorkers, exiting\n");
return 1;
}
WaitForSingleObject(hWait2Exit,INFINITE);
UnInitWinsock2();
return 1;
}

 

posted on 2007-08-17 12:56 聶文龍 閱讀(1107) 評論(0)  編輯 收藏 引用 所屬分類: net work
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美aaaaaaaa牛牛影院| 国产精品久久一卡二卡| 亚洲黄色高清| 久久久在线视频| 久久精品一区二区三区不卡牛牛| 一本综合精品| 亚洲综合视频一区| 先锋影音一区二区三区| 久久青青草综合| 亚洲第一在线综合网站| 亚洲国产一区二区精品专区| 日韩午夜在线观看视频| 亚洲欧美色婷婷| 久久精品最新地址| 欧美精品啪啪| 国产精品爽黄69| 在线欧美一区| 亚洲一区在线观看免费观看电影高清 | 亚洲国产精品一区二区尤物区| 国产亚洲欧美一级| 亚洲欧洲精品一区二区三区波多野1战4 | 亚洲男人av电影| 久久免费观看视频| 欧美色综合网| 在线观看欧美激情| 亚洲深夜激情| 美日韩精品免费观看视频| 亚洲人午夜精品免费| 久久精品成人一区二区三区| 欧美区日韩区| 激情综合五月天| 亚洲欧美中文另类| 亚洲高清资源| 久久国产日韩| 国产乱肥老妇国产一区二| 亚洲精品老司机| 免费观看成人鲁鲁鲁鲁鲁视频| 一区二区三区欧美| 欧美劲爆第一页| 亚洲成色精品| 久久久久免费观看| 亚洲欧美日韩国产一区二区| 欧美精品久久99| 在线观看91精品国产麻豆| 亚洲一二三区在线观看| 欧美国产日韩在线| 久久精品亚洲精品国产欧美kt∨| 国产精品美女久久福利网站| 在线亚洲一区二区| 国产一区二区日韩精品| 亚洲一区精品视频| 最新国产の精品合集bt伙计| 久久午夜国产精品| 国内精品一区二区三区| 久久av老司机精品网站导航| 亚洲视频免费观看| 国产精品vvv| 亚洲一区欧美一区| 亚洲视频狠狠| 国产精品视频网站| 欧美中文日韩| 欧美在线国产精品| 国产自产在线视频一区| 久久久久久综合| 久久精品男女| 亚洲激情综合| 亚洲娇小video精品| 欧美另类在线观看| 亚洲一区国产一区| 亚洲一区二区三区精品动漫| 国产精品一二三视频| 欧美在线播放一区二区| 香蕉尹人综合在线观看| 国产日产亚洲精品| 免费的成人av| 欧美日产国产成人免费图片| 亚洲免费视频中文字幕| 亚洲综合色网站| 今天的高清视频免费播放成人| 久久综合色播五月| 另类亚洲自拍| av成人天堂| 亚洲一区二区三区四区在线观看 | 亚洲精品中文字幕在线| 欧美精品一区在线| 欧美在线视频日韩| 蜜臀va亚洲va欧美va天堂| 91久久精品国产91久久| 亚洲欧洲日本一区二区三区| 欧美亚日韩国产aⅴ精品中极品| 久久国产精品久久w女人spa| 久久久久免费视频| 正在播放亚洲一区| 久久国产精品网站| 99视频热这里只有精品免费| 亚洲一区亚洲二区| 亚洲精品在线看| 午夜精品一区二区三区四区| 亚洲承认在线| 香港久久久电影| 亚洲精品国精品久久99热| 亚洲一区二区在线播放| 揄拍成人国产精品视频| 亚洲图片欧美午夜| 亚洲国产精品久久精品怡红院| 一区二区三区欧美亚洲| 亚洲人成人77777线观看| 香蕉久久夜色精品国产| 欧美日本不卡| 欧美综合77777色婷婷| 欧美大胆成人| 久久久久久久91| 欧美午夜一区| 亚洲三级国产| 在线精品一区二区| 亚洲欧美在线观看| 亚洲自拍偷拍一区| 嫩草伊人久久精品少妇av杨幂| 久久国产精彩视频| 国产精品成人一区二区网站软件 | 日韩视频免费观看高清在线视频 | 欧美美女日韩| 美女精品在线观看| 国产在线播精品第三| 亚洲一区二区三区精品视频| 一本久道久久综合狠狠爱| 久久亚洲春色中文字幕| 久久久久久欧美| 国产午夜精品美女毛片视频| a4yy欧美一区二区三区| 日韩视频在线一区二区| 模特精品在线| 亚洲韩国日本中文字幕| 亚洲国产精品视频| 麻豆精品视频在线观看| 欧美www视频| 亚洲激情一区| 欧美激情综合在线| 99热在线精品观看| 亚洲男人影院| 国产欧美精品日韩| 性18欧美另类| 媚黑女一区二区| 亚洲精品三级| 欧美日韩一区不卡| 亚洲一区二区精品| 久久精品国产一区二区电影 | 亚洲一区国产视频| 午夜伦欧美伦电影理论片| 国产精品一二三四区| 小处雏高清一区二区三区| 老司机免费视频一区二区| 尤物精品在线| 欧美精品成人一区二区在线观看| 亚洲美女色禁图| 欧美一区二区三区免费视频| 国户精品久久久久久久久久久不卡 | 免费视频一区二区三区在线观看| 欧美不卡在线视频| 日韩视频一区二区在线观看| 欧美午夜精品久久久久久浪潮| 午夜欧美精品久久久久久久| 欧美大片第1页| 亚洲一区在线免费观看| 国产综合香蕉五月婷在线| 欧美激情在线观看| 久久久天天操| 日韩视频在线免费观看| 国产精品女主播一区二区三区| 久久久久久电影| 99re6热只有精品免费观看| 久久精品夜色噜噜亚洲aⅴ| 亚洲理论电影网| 国产亚洲欧美日韩在线一区| 美女主播视频一区| 亚洲午夜在线观看视频在线| 欧美成人福利视频| 亚洲欧美综合v| 亚洲激情二区| 国产精品你懂得| 欧美激情免费观看| 欧美中文字幕在线观看| 一区二区三区欧美日韩| 欧美成人精品福利| 欧美一区二区三区视频免费| 亚洲精品乱码久久久久久| 国产欧美在线视频| 欧美无砖砖区免费| 久久最新视频| 欧美在线网站| 国产精品99久久久久久久女警| 欧美成ee人免费视频| 久久福利毛片| 亚洲欧美国产制服动漫| 99亚洲伊人久久精品影院红桃| 欧美色欧美亚洲另类七区| 免费人成网站在线观看欧美高清| 性欧美长视频| 欧美一区91| 亚洲男女自偷自拍|