|
http://www.codeproject.com/script/comments/forums.asp?msg=1338807&forumid=1647&mode=all&userid=1817418#xx1338807xx
This question has been answered many times i suppose. Also read Michael Dunn's FAQ. It has a lot of good information in it.
Regards,
Rajesh R. Subramanian.
You have an apple and me too. We exchange those and We have an apple each.
You have an idea and me too. We exchange those and We have two ideas each.
|
|
|
|
|
//iocpsever.cpp
#include <winsock2.h>
#include "memorypool.h"
#include <mswsock.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Mswsock.lib")
// 但I/O操作数据
typedef struct tagPER_IO_DATA
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
char buffer[1024];
DWORD BufferLen;
int OperationType;
SOCKET Socket;
SOCKADDR_STORAGE ClientAddr;
}PER_IO_DATA, *LPPER_IO_DATA;
#define OP_READ 0
#define OP_WRITE 1
#define OP_ACCEPT 2
particle_allocator<per_io_data> g_per_io_data;
HANDLE g_hAcceptExOverEvent = NULL;
DWORD WINAPI ServerWorkerThread(LPVOID lpParam);
using namespace std;
int main(void)
{
WSADATA wsd;
SYSTEM_INFO SystemInfo;
SOCKADDR_IN InternetAddr;
SOCKET Listen;
WSAStartup(MAKEWORD(2, 2), &wsd);
HANDLE CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
NULL,
0,
0);
GetSystemInfo(&SystemInfo);
for (DWORD i = 0; i < SystemInfo.dwNumberOfProcessors; ++i)
{
HANDLE ThreadHandle;
ThreadHandle = CreateThread(NULL,
0,
ServerWorkerThread,
CompletionPort,
0,
NULL);
CloseHandle(ThreadHandle);
}
Listen = WSASocket(AF_INET,
SOCK_STREAM,
0,
NULL,
0,
WSA_FLAG_OVERLAPPED);
InternetAddr.sin_family = PF_INET;
InternetAddr.sin_port = htons(10000);
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(Listen, (SOCKADDR*)&InternetAddr, sizeof(InternetAddr));
listen(Listen, 5);
if (CreateIoCompletionPort((HANDLE) Listen, CompletionPort, (ULONG_PTR)&Listen, 0) == NULL)
{
printf("CreateIoCompletionPort failed with error %d\n", GetLastError());
return 1;
}
g_hAcceptExOverEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if(!g_hAcceptExOverEvent)
{
return 1;
}
if(WSAEventSelect(Listen, g_hAcceptExOverEvent, FD_ACCEPT) == SOCKET_ERROR)
{
return 1;
}
SetEvent(g_hAcceptExOverEvent);
BOOL b = TRUE;
while (b)
{
if(WaitForSingleObject(g_hAcceptExOverEvent, INFINITE) == WAIT_FAILED)
continue;
for(int i =0;i<10;i++)
{
PER_IO_DATA * pper_io_data = NULL;
DWORD dwAddrLen = sizeof(sockaddr_in)+16;
pper_io_data = (PER_IO_DATA *)g_per_io_data.alloc_particle();
pper_io_data ->Socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
pper_io_data->OperationType = 2;
ZeroMemory(&pper_io_data->Overlapped,sizeof(OVERLAPPED));
if(!AcceptEx(Listen,pper_io_data ->Socket,pper_io_data ->buffer,0,dwAddrLen,dwAddrLen,&pper_io_data ->BufferLen,&pper_io_data->Overlapped))
{
if(WSAGetLastError() != ERROR_IO_PENDING)
{
closesocket(pper_io_data->Socket);
g_per_io_data.free_particle((void*)pper_io_data); //归还结构体到内存池
continue;
}
}
setsockopt( pper_io_data ->Socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, ( char* )&( Listen ), sizeof( Listen ) );
}
}
CloseHandle(g_hAcceptExOverEvent);
return 0;
}
DWORD WINAPI ServerWorkerThread(LPVOID lpParam)
{
HANDLE CompletionPort = (HANDLE)lpParam;
DWORD BytesTransferred;
LPOVERLAPPED lpOverlapped;
LPPER_IO_DATA poldPerIoData = NULL;
LPPER_IO_DATA pnewPerIoData = NULL;
DWORD RecvBytes;
DWORD Flags;
BOOL bRet = FALSE;
while (1)
{
bRet = GetQueuedCompletionStatus(CompletionPort,
&BytesTransferred,
(PULONG_PTR)
&poldPerIoData,
(LPOVERLAPPED*)
&lpOverlapped,
INFINITE);
if(!bRet)
{
continue;
}
poldPerIoData = (LPPER_IO_DATA)CONTAINING_RECORD(lpOverlapped,
PER_IO_DATA,
Overlapped);
switch (poldPerIoData->OperationType)
{
case OP_ACCEPT:
CreateIoCompletionPort(
(HANDLE)poldPerIoData->Socket,
CompletionPort,
(ULONG_PTR)0,
0);
pnewPerIoData = (LPPER_IO_DATA)g_per_io_data.alloc_particle();
if (!pnewPerIoData)
{
// Error
}
pnewPerIoData->Socket = poldPerIoData->Socket;
pnewPerIoData->OperationType = OP_READ;
ZeroMemory(&(pnewPerIoData->Overlapped), sizeof(OVERLAPPED));
Flags = 0;
pnewPerIoData->DataBuf.len = 1024;
pnewPerIoData->DataBuf.buf = pnewPerIoData->buffer;
pnewPerIoData->OperationType = 0; // read
WSARecv(pnewPerIoData->Socket,
&(pnewPerIoData->DataBuf),
1,
&RecvBytes,
&Flags,
&(poldPerIoData->Overlapped),
NULL);
g_per_io_data.free_particle((void*)poldPerIoData);
break;
case OP_READ:
cout << poldPerIoData->DataBuf.buf << endl;
pnewPerIoData = (LPPER_IO_DATA)g_per_io_data.alloc_particle();
if (!pnewPerIoData)
{
// Error
}
pnewPerIoData->Socket = poldPerIoData->Socket;
pnewPerIoData->OperationType = OP_READ;
ZeroMemory(&(pnewPerIoData->Overlapped), sizeof(OVERLAPPED));
Flags = 0;
pnewPerIoData->DataBuf.len = 1024;
pnewPerIoData->DataBuf.buf = pnewPerIoData->buffer;
pnewPerIoData->OperationType = 0; // read
WSARecv(pnewPerIoData->Socket,
&(pnewPerIoData->DataBuf),
1,
&RecvBytes,
&Flags,
&(poldPerIoData->Overlapped),
NULL);
g_per_io_data.free_particle((void*)poldPerIoData);
break;
case OP_WRITE:
break;
}
}
}
//memorypool.h
#pragma once
#include <iostream>
#include <list>#include <windows.h>
//关键区锁
class CLock
{
CRITICAL_SECTION _crisection;
public:
CLock()
{
InitializeCriticalSection( &_crisection );
}
~CLock()
{
DeleteCriticalSection( &_crisection );
}
void lock()
{
EnterCriticalSection( &_crisection );
}
void unlock()
{
LeaveCriticalSection( &_crisection );
}
};
template <class particle="">
class particle_allocator
{
enum
{
chunk_size =1024
};
typedef unsigned char byte;
struct particle_list
{
byte *_data;
particle_list *_next;
};
std::list<byte *=""> _chunks;
particle_list* _free_list;
CLock _guard;
public:
particle_allocator()
{
_free_list = 0;
_used_particle_number = 0;
_free_particle_number = 0;
}
~particle_allocator()
{
for(std::list<byte *="">::iterator iter = _chunks.begin();iter!=_chunks.end();++iter)
{
delete [] (*iter);
}
while(_free_list)
{
particle_list *temp = _free_list;
_free_list = _free_list->_next;
delete temp;
}
}
particle* alloc_particle()
{
_guard.lock();
byte *momory;
particle_list* ¤t_list = _free_list;
if(!current_list)
{
momory = new byte[chunk_size*sizeof(particle)];
_chunks.push_front(momory);
for(int i =0;i< chunk_size;i++,_free_particle_number++)
{
particle_list *newnode = new particle_list;
newnode->_data = momory + i*sizeof(particle);
newnode->_next = current_list;
current_list = newnode;
}
}
byte *redata;
particle_list *de_node = current_list;
redata = _free_list->_data;
current_list = current_list->_next;
++_used_particle_number;
--_free_particle_number;
delete de_node;
_guard.unlock();
return new(redata) particle;
}
void free_particle(void *p)
{
byte *free_block = reinterpret_cast<byte *="">(p);
_guard.lock();
particle_list* ¤t_list = _free_list;
particle_list *newnode = new particle_list;
newnode->_data = free_block;
newnode->_next = current_list;
current_list = newnode;
--_used_particle_number;
++_free_particle_number;
_guard.unlock();
}
void getallocator()
{
using namespace std;
cout << "_used_particle_number is " << _used_particle_number << " _free_particle_number is "<< _free_particle_number << endl;
}
public:
size_t _used_particle_number;
size_t _free_particle_number;
};
01 is program
|
|
|
|
|
Unless you explain the problem to us how can we help you.
Reading this code itself is tiresome. Being specific about your problem will help you and us.
Nibu thomas
Software Developer
Programming Tips[^]
|
|
|
|
|
WSARecv(pnewPerIoData->Socket,
&(pnewPerIoData->DataBuf),
1,
&RecvBytes,
&Flags,
&(poldPerIoData->Overlapped),
NULL);
my program have a spelling mistake.
&(poldPerIoData->Overlapped)
&(pnewPerIoData->Overlapped)
01 is program
|
|
|
|
|
How can I read parallel port for less than 1 miliseconds(about 40 microsecond)with VC++
|
|
|
|
|
Hi
Please try
http://www.codeproject.com/system/AsefPortAccess.asp
KK
|
|
|
|
|
|
I would like to round a LONG to a multiple of an other LONG. For example: I have got the number 5 and i would like to round it up to a multiple of 3. I wrote the following code to do this:
lCurrent=((lMinimum+(lIncrement-1))/lIncrement)*lIncrement;
In this piece of code lMinimum is de value that gets rounded up. And lIncrement is the value to wich lMinimum is rounded up. So if we choose the numbers mentioned above we get 6. This works fine for positive numbers but when we choose a negative number for lMinimum it goes wrong. I wrote another piece of code to handle negative numbers
lCurrent=abs(lMinimum%lIncrement)+lMinimum;
So combining the two we get:
if(lMinimum>=0)
{
lCurrent=((lMinimum+(lIncrement-1))/lIncrement)*lIncrement;
}
else
{
lCurrent=abs(lMinimum%lIncrement)+lMinimum;
}
This is the obvious way and it contains one conditional branch. I was wondering of someone came accros a bit twiddling hack to do this more efficient.
Thanks
|
|
|
|
|
Remco Hoogenboezem wrote: I have got the number 5 and i would like to round it up to a multiple of 3.
From the example you suggested...
LONG round = 5 - ( 5 % 3 );
LONG round = ( 5 + 3 ) - (( 5 + 3 ) % 3 ); This should round it...
All 5's and 3's should be replaced by variable names...
You should replace 5 + 3 with another variable name so it will look good.
Nibu thomas
Software Developer
Programming Tips
|
|
|
|
|
Remco Hoogenboezem wrote: I would like to round a LONG to a multiple of an other LONG. For example: I have got the number 5 and i would like to round it up to a multiple of 3
Funny but it works
Suppose your number is 5 and round it with multiple of 3
LONG iNum=5;
LONG iMultipleof=3;
LONG iResult;
iResult=(iNum/iMultipleof)*iMultipleof; Try it! But it works for less rounding
Knock out 't' from can't,
You can if you think you can
|
|
|
|
|
The end objective is to save a file to disk with data from a linked list. First this function converts the data already in the list into a buffer (string), which is sent along with the filename to another function (not listed here) so that the buffer is written to file. The problem is where I try to set the temporary variables which store the fields in the linked list so that they can be concatinated together into individual lines...to be later concatinated into the buffer (a c++ string). I'm getting this error 4 times from the compiler:
error C2110: '+' cannot add two pointers
The function with the problem:
<br />
void WeaveList::SaveToFile(string FileName)<br />
{<br />
NodePtr currPtr = head;
bool WriteSucceeded = false;<br />
string WeaveLine1,<br />
WeaveLine2,<br />
WeaveLine3,<br />
WeaveLine4,<br />
Buffer,<br />
tempWeaveName,<br />
tempExampleSizes;<br />
double tempARMin,<br />
tempARMax = 0.0;<br />
int tempNumRings = 0;<br />
<br />
cout<<"Writing data to buffer..."<<endl;<br />
if(!IsEmpty())<br />
{<br />
while(currPtr != NULL)<br />
{<br />
tempARMin = currPtr->AR_Range_Min;<br />
tempARMax = currPtr->AR_Range_Max;<br />
tempNumRings = currPtr->NumRingsUsed;<br />
tempWeaveName = currPtr->WeaveName;<br />
tempExampleSizes = currPtr->ExampleSizes;<br />
<br />
WeaveLine1 = "Weave AR Range: " + "/t/t" + tempARMin + " - " + tempARMax;<br />
WeaveLine2 = "Number of Rings Used:" + "/t/t" + tempNumRings;<br />
WeaveLine3 = "Weave Name:" + "/t/t/t" + "!" + tempWeaveName;<br />
WeaveLine4 = "Example Ring Sizes:" + "/t/t" + "!" + tempExampleSizes;<br />
Buffer = Buffer + WeaveLine1 + "/n" + WeaveLine2 + "/n" + WeaveLine3 + "/n" + WeaveLine4;<br />
if(currPtr->link != NULL)<br />
Buffer = Buffer + "/n/n";<br />
currPtr = currPtr->link;
}<br />
}<br />
else<br />
Buffer = "";<br />
WriteSucceeded = SaveListToFile(FileName, Buffer);
if(WriteSucceeded)<br />
cout<<"SUCCESS!"<<endl;<br />
else<br />
cout<<"F***! Unable to write to file."<<endl;
I'm doing this totally on my own without an instructor to pester with questions, so any help would be appreciated. I can post the rest of the file if anyone wants, but it's kind of long.
-- modified at 15:53 Friday 19th May, 2006
|
|
|
|
|
CoffeeAddict19 wrote: "Weave AR Range: " + "/t/t" + tempARMin + " - "
That is not going to work. Take a look at the STL stringstream class.
"What classes are you using ? You shouldn't call stuff if you have no idea what it does" Christian Graus in the C# forum
led mike
|
|
|
|
|
Overload the "+" operator to adding two strings.
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
CoffeeAddict19 wrote: WeaveLine1 = "Weave AR Range: " + "/t/t" + tempARMin + " - " + tempARMax;
Use assign method of string like following:
WeaveLine1.assign("Weave AR Range: " + "/t/t" + tempARMin + " - " + tempARMax); CoffeeAddict19 wrote: Buffer = Buffer + WeaveLine1 + "/n" + WeaveLine2 + "/n" + WeaveLine3 + "/n" + WeaveLine4;
for appending use following code
Buffer.append(WeaveLine1 + "/n" + WeaveLine2 + "/n" + WeaveLine3 + "/n" + WeaveLine4);
Knock out 't' from can't,
You can if you think you can
|
|
|
|
|
I am new to windows and C++ programming. I am developing an evc++ 4.0 application for a handheld computer running CE .NET 4.2.I have a dialog with many editbox, combobox and datetime picker controls. At runtime it may be determined that some of the data should be unavailable for update so I'd like to remove the corresponding controls from the tab order. I've tried modifying the z-order using SetWindowPos and I can modify the tab order,
however, what I really need to do is to remove some controls from the tab order. Is there any way to modify the tabstop property for a control at runtime?
sande
|
|
|
|
|
You've probably figured it out by now, but...
I think what you want to do is disable the controls that can't be updated. You should be able to use EnableWindow(false) function to disable the controls dynamically. The OS should exlude disabled controls from the tab order automatically. I assume it works in the embedded environment as well - give it a shot.
- S
50 cups of coffee and you know it's on!
|
|
|
|
|
Hi, Steve.
That is exactly what I was looking for. Thanks very much for your assistance.
|
|
|
|
|
I'm sure there is a simple solution to my problem but I'm just not seeing it. I'm trying to update my views as I read data from a file. I have implemented a separate thread so that the program is able to respond to other command while it is reading. Because of this I cannot use UpdateAllViews() . I tried using events, which worked, but with some undesired side effects. The next approach would be to post a message and have the views update on this. So far I have in my CDocument:
::PostMessage(HWND_BROADCAST, UWM_UPDATE_VIEW, 0, 0);
And in the CView I have:
BEGIN_MESSAGE_MAP(CAESView, CView)<br />
ON_REGISTERED_MESSAGE(UWM_UPDATE_VIEW, Update)<br />
END_MESSAGE_MAP()<br />
<br />
LRESULT CAESView::Update(WPARAM wParam, LPARAM lParam)<br />
{<br />
return 0;<br />
}
The code compiles and runs but my CView never responds to the message. Am I missing something?
Thanks.
|
|
|
|
|
Hi, I'm not sure about UWM_UPDATE_VIEW message and how MFC handles it but PostMessage with HWND_BROADCAST sends the message to all top-level windows and a CView usually is a child windows of a frame.
The main window should capture your registered message and make the view updates.
Best regards,
Mauro.
|
|
|
|
|
If you do some reading about how CCmdTarget dispatches messages to the MFC framework I bet you find that it does not support HWND_BROADCAST. You will have to handle that in a parent location like your CFrameWnd class and provide child notification yourself.
"What classes are you using ? You shouldn't call stuff if you have no idea what it does" Christian Graus in the C# forum
led mike
|
|
|
|
|
|
Hi, I'm a student playing around with c++ windows forms in .net 2003. That said, I have a quick question. I can't seem to access the data my iterator is pointing at. All the examples of iterators I can find show that I am doing it right. Is there something with windows forms that changes things?
The Code:
typedef std::vector<int> StatsVector;
//create a vector to hold the random numbers
StatsVector stats;
StatsVector::iterator statIter;
statIter = stats.begin();
int tempStat = 0;
//populate the vector with 6 random integers
for(int i = 0; i < 6; i++)
{
stats.push_back(randomNum());
}
//display the results in the designated text box
tempStat = *statIter;
str->Text = tempStat.ToString("G");
statIter++;
tempStat = *statIter;
dex->Text = tempStat.ToString("G");
statIter++;
tempStat = *statIter;
con->Text = tempStat.ToString("G");
statIter++;
tempStat = *statIter;
intel->Text = tempStat.ToString("G");
statIter++;
tempStat = *statIter;
wis->Text = tempStat.ToString("G");
statIter++;
tempStat = *statIter;
chr->Text = tempStat.ToString("G");
//this is how it worked without iterators randomNum returns an int
//str->Text = randomNum().ToString("G");
If anyone wants the project files to compile them, I can email them to you.
If you know of a good book that covers all these vc++ windows forms then please post it.
Thanks,
Matt
|
|
|
|
|
Not sure but try getting the iterator after you load the vector
statIter = stats.begin();
"What classes are you using ? You shouldn't call stuff if you have no idea what it does" Christian Graus in the C# forum
led mike
|
|
|
|
|
Thank You, That fixed it.
Now I feel kinda stupid, at least I won't forget how to use iterators in this way... I hope.
Matt
|
|
|
|
|
Hi again
In windef.h we can see these defines :
#define LOBYTE(w) ((BYTE)((DWORD_PTR)(w) & 0xff))
#define HIBYTE(w) ((BYTE)((DWORD_PTR)(w) >> 8))
I don't understand how HIBYTE gets, most significant byte, by above code.
With LOBYTE all is clear.
I thought these macros were getting bytes from 32 bit value.
It found out they are for 16 bit values, now all is clear
thanks.
-- modified at 14:36 Friday 19th May, 2006
|
|
|
|
|