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

隨筆 - 298  文章 - 377  trackbacks - 0
<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

常用鏈接

留言簿(34)

隨筆分類

隨筆檔案

文章檔案

相冊(cè)

收藏夾

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

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) 評(píng)論(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>
            欧美中文在线观看国产| 久久精品成人一区二区三区蜜臀 | 久久精品国产v日韩v亚洲| 亚洲嫩草精品久久| 亚洲男人av电影| 欧美中文日韩| 免费欧美高清视频| 亚洲人成网站色ww在线| 亚洲啪啪91| 中文网丁香综合网| 欧美一区免费视频| 免播放器亚洲| 欧美人在线视频| 国产精品视频自拍| 亚洲大胆美女视频| 一区二区三区www| 欧美在线看片a免费观看| 猫咪成人在线观看| 日韩一级在线观看| 久久er99精品| 欧美日韩国产首页| 国产一区二区中文字幕免费看| 在线成人av| 亚洲最黄网站| 久久久久在线观看| 一区二区三区免费看| 久久久av网站| 欧美婷婷在线| 在线观看欧美日本| 欧美亚洲在线观看| 欧美激情影音先锋| 性色av一区二区三区红粉影视| 欧美国产精品v| 国内自拍一区| 亚洲欧美日韩在线观看a三区 | 欧美日韩一区在线观看视频| 国产亚洲欧美一区二区| 9l视频自拍蝌蚪9l视频成人| 久久裸体艺术| 亚洲一区二区在线播放| 欧美激情综合色| 1024亚洲| 久久久久久久尹人综合网亚洲| 亚洲人成毛片在线播放| 午夜在线精品偷拍| 欧美大片免费看| 午夜精品久久| 一区二区三区三区在线| 欧美激情一二三区| 亚洲国产成人在线| 久久免费视频在线| 亚洲欧美综合另类中字| 欧美午夜精品久久久久免费视| 最新亚洲视频| 欧美成人激情视频| 老司机久久99久久精品播放免费| 国产有码一区二区| 久久精品网址| 欧美在线亚洲| 黑人巨大精品欧美黑白配亚洲| 久久国产精品一区二区| 香蕉久久a毛片| 国产欧美日韩免费看aⅴ视频| 亚洲网站在线| 日韩一级视频免费观看在线| 欧美精品二区| 一区二区电影免费在线观看| 亚洲精品孕妇| 国产精品成人一区二区三区吃奶 | 一区在线播放| 欧美福利视频在线观看| 欧美国产日产韩国视频| 一本不卡影院| 99在线热播精品免费| 国产精品久久久| 久久精品三级| 久久亚洲综合色| 亚洲毛片在线观看| 9i看片成人免费高清| 国产精品入口夜色视频大尺度| 欧美一区二区在线播放| 久久精品国产免费看久久精品| 亚洲第一综合天堂另类专| 亚洲日本国产| 国产欧美精品xxxx另类| 毛片一区二区| 欧美粗暴jizz性欧美20| 亚洲一区二区av电影| 亚洲在线播放| 在线成人中文字幕| 99国产精品久久久久久久久久 | 一二三区精品福利视频| 国产日韩成人精品| 亚洲电影专区| 国产精品视频免费观看| 免费看av成人| 欧美午夜不卡在线观看免费 | 在线视频精品一区| 狠久久av成人天堂| 91久久精品美女| 亚洲综合色在线| 久久国内精品自在自线400部| 亚洲国产精品一区二区三区| 99国产精品久久久久老师| 国产在线欧美日韩| 中文av一区特黄| 久久国产精品久久久久久久久久 | 欧美日韩精品在线观看| 久久男人资源视频| 欧美日韩国产一区| 欧美aⅴ99久久黑人专区| 国产精品女同互慰在线看| 欧美顶级艳妇交换群宴| 国产精品入口| 亚洲精品一二三| 在线观看日韩av| 亚洲女同精品视频| 中文av字幕一区| 欧美aaa级| 欧美aaaaaaaa牛牛影院| 国产视频观看一区| 国产精品99久久久久久久女警| 亚洲黄色av| 久久久久久一区| 久久爱www| 国产毛片一区二区| 一本一本久久a久久精品综合妖精| 亚洲精品欧美专区| 久久手机精品视频| 久久夜色精品亚洲噜噜国产mv| 欧美午夜美女看片| 一二美女精品欧洲| 亚洲天堂成人| 欧美日韩在线一区二区| 亚洲欧洲一二三| 91久久国产综合久久91精品网站 | 国产精品日韩在线| 日韩亚洲一区二区| 一区二区三区免费网站| 欧美日韩国产一区| 亚洲欧洲综合| 99精品久久| 欧美日韩视频在线第一区| 亚洲精品国产精品乱码不99按摩| 91久久精品一区二区别| 久久综合网hezyo| 欧美国产一区在线| 亚洲三级观看| 欧美日韩福利在线观看| 亚洲日本激情| 国产精品99久久久久久久久| 欧美午夜精品久久久久久孕妇| 在线一区二区三区四区| 久久国产精品久久久久久电车| 国内精品久久久久国产盗摄免费观看完整版| 亚洲一区二区三区精品在线| 久久精品系列| 亚洲肉体裸体xxxx137| 欧美日韩久久| 亚洲婷婷综合色高清在线 | 女主播福利一区| 亚洲人www| 亚洲综合日韩在线| 国内揄拍国内精品久久| 欧美国产第二页| 一本一道久久综合狠狠老精东影业 | 久久精品人人做人人综合| 狠狠色丁香婷婷综合影院| 老**午夜毛片一区二区三区| 亚洲精品美女91| 欧美怡红院视频| 亚洲欧洲三级| 国产精品久久久久久久久久ktv| 欧美在线观看你懂的| 亚洲国产精品女人久久久| 亚洲欧美在线磁力| 亚洲国产成人精品视频| 国产精品久久久久久一区二区三区| 亚洲欧美999| 亚洲国产日韩欧美综合久久| 欧美一区二区| 艳女tv在线观看国产一区| 国产伦精品一区二区三区免费| 另类综合日韩欧美亚洲| 亚洲午夜高清视频| 欧美成人精品一区| 性欧美video另类hd性玩具| 亚洲精品一级| 国内精品模特av私拍在线观看| 欧美日韩直播| 欧美激情亚洲国产| 久久精品国产第一区二区三区最新章节 | 欧美福利在线观看| 欧美伊人久久| 中文欧美日韩| 亚洲精选中文字幕| 亚洲国产成人久久综合一区| 国产亚洲精品成人av久久ww| 欧美调教vk| 欧美日韩在线播放|