madhusudankapoor
October 17th, 2005, 12:23 AM
Let me confess that I am fresher in network programming can any one help me???
I made very simple server using IOCP but my server is unable to receive all the message. Here is code for my server
#include "stdafx.h"
//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include "winsock2.h"
#include "fstream"
#include "conio.h"
#include "stdio.h"
#pragma comment(lib,"ws2_32.lib")
/*--- MACRO Defination --*/
#define SERVER_PORT htons(8888)
#define DATA_BUFSIZE 4096
#define OP_READ 0
#define OP_WRITE 1
#define OP_ACCEPT 2
/* OverlapPlus Data Used to store Ovelap info and other information need to user*/
typedef struct _OVERLAPPEDPLUS
{
OVERLAPPED Overlapped;
SOCKET sServer,sClient;
int nOperationCode;
WSABUF wbuf;
DWORD dwBytes,dwFlags;
SOCKADDR_STORAGE ClientAddr;
int nClientNumber;
}OVERLAPPEDPLUS, * LP_OVERLAP_PLUS;
void Initialize();
DWORD WINAPI ServerWorkerThread(LPVOID lpParam);
FILE *stream;
void appendLog(TCHAR* strMessage)
{
stream = _wfopen( _T("c:\\iServer.log"), _T("a") );
fputws(_T("\n"),stream);
fputws(strMessage,stream);
fclose( stream );
}
int main()
{
WSADATA wsd;
SYSTEM_INFO SystemInfo;
SOCKADDR_IN InternetAddr;
SOCKET sListen;
HANDLE hIocp;
int nClientInc = 1;
/* Initialize Winsock2 */
Initialize();
/*--- Create an I/O completion port ---*/
hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, (ULONG_PTR)0, 0);
if(NULL == hIocp)
{
printf("Error in initialization of Completion Port! Press any to exit...");
return -1;
}
/* Determine how many processors are on the system, For thead optimization */
GetSystemInfo(&SystemInfo);
/*--- Create worker threads based on the number of processors available on the system ---*/
for(int nProcessor = 0; nProcessor < (int) SystemInfo.dwNumberOfProcessors; nProcessor++)
{
HANDLE ThreadHandle;
ThreadHandle = CreateThread(NULL, 0,ServerWorkerThread, hIocp,0, NULL);
//CloseHandle(ThreadHandle); // Why We close thread Handle ?????
}
/*--- Create a listening socket --- */
sListen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,WSA_FLAG_OVERLAPPED);
/*--- Fill TCP Header Info for bind a socket ---*/
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = SERVER_PORT;
/*-- Bind the socket with port --*/
bind(sListen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr));
/*--- Prepare socket for listening mode and Start the Server ---*/
listen(sListen, 5);
printf("Server Started in listen mode ....");
while(TRUE)
{
int ret;
char strBuffer[DATA_BUFSIZE];
ULONG_PTR *PerHandleKey;
OVERLAPPED *Overlap;
OVERLAPPEDPLUS *OverlapPlus,*olpClientOverlappedPlusData;
DWORD dwBytesXfered;
SOCKET sClient;
SOCKADDR_IN saRemote;
int nRemoteLen;
/*-- Accept connections and assign to the completion port--*/
nRemoteLen = sizeof(saRemote);
sClient = WSAAccept(sListen, (SOCKADDR *)&saRemote,&nRemoteLen,0 , 0);
printf("New Client! Socket number %d connected\n", sClient);
/* Allocate memory to olpClientOverlappedPlusData */
olpClientOverlappedPlusData = (LP_OVERLAP_PLUS)GlobalAlloc(GPTR, sizeof(OVERLAPPEDPLUS));
if(NULL == olpClientOverlappedPlusData)
{
printf("Error in initialization Memory! Press any to exit...");
return -1;
}
/*-- Fill OverlapPlusData -- */
olpClientOverlappedPlusData->sClient = sClient;
olpClientOverlappedPlusData->nClientNumber = nClientInc++;
olpClientOverlappedPlusData->nOperationCode = OP_READ;
olpClientOverlappedPlusData->wbuf.buf = strBuffer;
olpClientOverlappedPlusData->wbuf.len = DATA_BUFSIZE;
memcpy(&olpClientOverlappedPlusData->ClientAddr, &saRemote, nRemoteLen);
// Associate the accepted socket with the completion port
if(NULL == CreateIoCompletionPort((HANDLE)sClient, hIocp,(ULONG_PTR)0,0) )
{
printf("Error in initialization of Completion Port for server! Press any to exit...");
return -1;
}
/*-- Make Ready to Recive Data From given Port -- */
ret = WSARecv(sClient,&olpClientOverlappedPlusData->wbuf,1,&olpClientOverlappedPlusData->dwBytes,&olpClientOverlappedPlusData->dwFlags,&olpClientOverlappedPlusData->Overlapped, NULL);
}
return 0;
}
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
/*-- Notify Starting of server -- */
printf("\nHello Server Started, I am in worker thread! \n");
HANDLE hIocp = (HANDLE) CompletionPortID;
ULONG_PTR *PerHandleKey;
OVERLAPPED *Overlap;
OVERLAPPEDPLUS *OverlapPlus,*newolp;
DWORD dwBytesXfered;
int ret;
char *strData ;
while (1)
{
ret = GetQueuedCompletionStatus(hIocp,&dwBytesXfered,(PULONG_PTR)&PerHandleKey,&Overlap,INFINITE);
if (ret == 0){
continue;
}
OverlapPlus = CONTAINING_RECORD(Overlap, OVERLAPPEDPLUS, Overlapped);
/*--- Process Data According to Operation Code ---*/
switch (OverlapPlus->nOperationCode )
{
case OP_READ:
// Process the data read Repost the read if necessary, reusing the same receive buffer as before
memset(&OverlapPlus->Overlapped, 0, sizeof(OVERLAPPED));
ret = WSARecv(OverlapPlus->sClient,&OverlapPlus->wbuf,1,&OverlapPlus->dwBytes,&OverlapPlus->dwFlags,&OverlapPlus->Overlapped, NULL);
appendLog((TCHAR*) &OverlapPlus->wbuf.buf[0]);
ZeroMemory(&(OverlapPlus->Overlapped),sizeof(OVERLAPPED));// Why we reset memory ???
printf("\n\n****Inforamtion*****\n\nClient Socket:%d \n Bytes:%d \n Buff :%s \n Client No: %d\n FLAG :%d ",(int)OverlapPlus->sClient,OverlapPlus->dwBytes,OverlapPlus->wbuf.buf,OverlapPlus->nClientNumber,OverlapPlus->dwFlags);
if (ret == SOCKET_ERROR)
{
ret = WSAGetLastError();
if ( ret != WSA_IO_PENDING)
{
// What should i do in case of Error???
//printf("Error occur at WSARecv() : %d", ret);
//ExitThread(0);
break;
}
}
break;
case OP_WRITE:
// Process the data sent, etc.
break;//…
}
}
}
void Initialize()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
printf("\n couldn't find a useable winsock.dll");
exit(1);
}
}
I made very simple server using IOCP but my server is unable to receive all the message. Here is code for my server
#include "stdafx.h"
//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include "winsock2.h"
#include "fstream"
#include "conio.h"
#include "stdio.h"
#pragma comment(lib,"ws2_32.lib")
/*--- MACRO Defination --*/
#define SERVER_PORT htons(8888)
#define DATA_BUFSIZE 4096
#define OP_READ 0
#define OP_WRITE 1
#define OP_ACCEPT 2
/* OverlapPlus Data Used to store Ovelap info and other information need to user*/
typedef struct _OVERLAPPEDPLUS
{
OVERLAPPED Overlapped;
SOCKET sServer,sClient;
int nOperationCode;
WSABUF wbuf;
DWORD dwBytes,dwFlags;
SOCKADDR_STORAGE ClientAddr;
int nClientNumber;
}OVERLAPPEDPLUS, * LP_OVERLAP_PLUS;
void Initialize();
DWORD WINAPI ServerWorkerThread(LPVOID lpParam);
FILE *stream;
void appendLog(TCHAR* strMessage)
{
stream = _wfopen( _T("c:\\iServer.log"), _T("a") );
fputws(_T("\n"),stream);
fputws(strMessage,stream);
fclose( stream );
}
int main()
{
WSADATA wsd;
SYSTEM_INFO SystemInfo;
SOCKADDR_IN InternetAddr;
SOCKET sListen;
HANDLE hIocp;
int nClientInc = 1;
/* Initialize Winsock2 */
Initialize();
/*--- Create an I/O completion port ---*/
hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, (ULONG_PTR)0, 0);
if(NULL == hIocp)
{
printf("Error in initialization of Completion Port! Press any to exit...");
return -1;
}
/* Determine how many processors are on the system, For thead optimization */
GetSystemInfo(&SystemInfo);
/*--- Create worker threads based on the number of processors available on the system ---*/
for(int nProcessor = 0; nProcessor < (int) SystemInfo.dwNumberOfProcessors; nProcessor++)
{
HANDLE ThreadHandle;
ThreadHandle = CreateThread(NULL, 0,ServerWorkerThread, hIocp,0, NULL);
//CloseHandle(ThreadHandle); // Why We close thread Handle ?????
}
/*--- Create a listening socket --- */
sListen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,WSA_FLAG_OVERLAPPED);
/*--- Fill TCP Header Info for bind a socket ---*/
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = SERVER_PORT;
/*-- Bind the socket with port --*/
bind(sListen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr));
/*--- Prepare socket for listening mode and Start the Server ---*/
listen(sListen, 5);
printf("Server Started in listen mode ....");
while(TRUE)
{
int ret;
char strBuffer[DATA_BUFSIZE];
ULONG_PTR *PerHandleKey;
OVERLAPPED *Overlap;
OVERLAPPEDPLUS *OverlapPlus,*olpClientOverlappedPlusData;
DWORD dwBytesXfered;
SOCKET sClient;
SOCKADDR_IN saRemote;
int nRemoteLen;
/*-- Accept connections and assign to the completion port--*/
nRemoteLen = sizeof(saRemote);
sClient = WSAAccept(sListen, (SOCKADDR *)&saRemote,&nRemoteLen,0 , 0);
printf("New Client! Socket number %d connected\n", sClient);
/* Allocate memory to olpClientOverlappedPlusData */
olpClientOverlappedPlusData = (LP_OVERLAP_PLUS)GlobalAlloc(GPTR, sizeof(OVERLAPPEDPLUS));
if(NULL == olpClientOverlappedPlusData)
{
printf("Error in initialization Memory! Press any to exit...");
return -1;
}
/*-- Fill OverlapPlusData -- */
olpClientOverlappedPlusData->sClient = sClient;
olpClientOverlappedPlusData->nClientNumber = nClientInc++;
olpClientOverlappedPlusData->nOperationCode = OP_READ;
olpClientOverlappedPlusData->wbuf.buf = strBuffer;
olpClientOverlappedPlusData->wbuf.len = DATA_BUFSIZE;
memcpy(&olpClientOverlappedPlusData->ClientAddr, &saRemote, nRemoteLen);
// Associate the accepted socket with the completion port
if(NULL == CreateIoCompletionPort((HANDLE)sClient, hIocp,(ULONG_PTR)0,0) )
{
printf("Error in initialization of Completion Port for server! Press any to exit...");
return -1;
}
/*-- Make Ready to Recive Data From given Port -- */
ret = WSARecv(sClient,&olpClientOverlappedPlusData->wbuf,1,&olpClientOverlappedPlusData->dwBytes,&olpClientOverlappedPlusData->dwFlags,&olpClientOverlappedPlusData->Overlapped, NULL);
}
return 0;
}
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
/*-- Notify Starting of server -- */
printf("\nHello Server Started, I am in worker thread! \n");
HANDLE hIocp = (HANDLE) CompletionPortID;
ULONG_PTR *PerHandleKey;
OVERLAPPED *Overlap;
OVERLAPPEDPLUS *OverlapPlus,*newolp;
DWORD dwBytesXfered;
int ret;
char *strData ;
while (1)
{
ret = GetQueuedCompletionStatus(hIocp,&dwBytesXfered,(PULONG_PTR)&PerHandleKey,&Overlap,INFINITE);
if (ret == 0){
continue;
}
OverlapPlus = CONTAINING_RECORD(Overlap, OVERLAPPEDPLUS, Overlapped);
/*--- Process Data According to Operation Code ---*/
switch (OverlapPlus->nOperationCode )
{
case OP_READ:
// Process the data read Repost the read if necessary, reusing the same receive buffer as before
memset(&OverlapPlus->Overlapped, 0, sizeof(OVERLAPPED));
ret = WSARecv(OverlapPlus->sClient,&OverlapPlus->wbuf,1,&OverlapPlus->dwBytes,&OverlapPlus->dwFlags,&OverlapPlus->Overlapped, NULL);
appendLog((TCHAR*) &OverlapPlus->wbuf.buf[0]);
ZeroMemory(&(OverlapPlus->Overlapped),sizeof(OVERLAPPED));// Why we reset memory ???
printf("\n\n****Inforamtion*****\n\nClient Socket:%d \n Bytes:%d \n Buff :%s \n Client No: %d\n FLAG :%d ",(int)OverlapPlus->sClient,OverlapPlus->dwBytes,OverlapPlus->wbuf.buf,OverlapPlus->nClientNumber,OverlapPlus->dwFlags);
if (ret == SOCKET_ERROR)
{
ret = WSAGetLastError();
if ( ret != WSA_IO_PENDING)
{
// What should i do in case of Error???
//printf("Error occur at WSARecv() : %d", ret);
//ExitThread(0);
break;
}
}
break;
case OP_WRITE:
// Process the data sent, etc.
break;//…
}
}
}
void Initialize()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
printf("\n couldn't find a useable winsock.dll");
exit(1);
}
}