|
I think i understand you. You basicly wait for events Once you get a read event you start a thread to handle that event and read the fifo. But, before you start that thread you make sure the past current read thead has terminate.
I like the sounds of this socket. Do you have it posted up here. Send me a copy. Please....
Right now, I am going to try simpler versiion of that, I am going to do all my reads and write in the same thread. It will attempt to write one packet, than read one packet and it will never block.. But, I am betting this will not working my application. My new code below.. Let
<br />
case LOOP_CLIENT:<br />
WSAEnumNetworkEvents(client_socket, g_hClientEvent, &NetworkClientEvents);<br />
if( NetworkClientEvents.lNetworkEvents == FD_CLOSE)<br />
{ <br />
printf("Client Socket Closed Message: \n\r"); <br />
WSACloseEvent(g_hClientEvent);<br />
closesocket(client_socket);<br />
WSACleanup();<br />
state = CONNECT_CLIENT;<br />
}<br />
<br />
if( NetworkClientEvents.lNetworkEvents == FD_CONNECT)<br />
{<br />
if (0 != NetworkClientEvents.iErrorCode[FD_CONNECT_BIT]) {<br />
printf("Client Connection Failed: \n\r"); <br />
state = CONNECT_CLIENT;<br />
}else{ <br />
printf("Client Connected Message: \n\r");<br />
state = LOOP_CLIENT;<br />
}<br />
}<br />
<br />
<br />
<br />
if( txbytesremaining == 0 )<br />
{<br />
if( TxQueue.Pop( &temp_txpacket) == true)<br />
{ <br />
temp_txbuffer = (char *)&temp_txpacket; <br />
int txbytesremaining = sizeof(temp_txbuffer); <br />
iResults = send( client_socket, (char *)temp_txbuffer, txbytesremaining, NULL ); <br />
if( iResults != SOCKET_ERROR ) <br />
{ <br />
txbytesremaining -= iResults;<br />
if (txbytesremaining > 0) <br />
temp_txbuffer += iResults;
}else{ <br />
break; <br />
} <br />
}<br />
}else{<br />
iResults = send( client_socket, (char *)temp_txbuffer, txbytesremaining, NULL ); <br />
if( iResults != SOCKET_ERROR ) <br />
{ <br />
txbytesremaining -= iResults;<br />
if (txbytesremaining > 0)<br />
temp_txbuffer += iResults;
}else{<br />
break;
}<br />
}<br />
<br />
<br />
<br />
if( rxbytesremaining == 0 )<br />
rxbytesremaining = sizeof(temp_rxbuffer);<br />
<br />
iResults = recv( client_socket, (char *)temp_rxbuffer, rxbytesremaining, NULL ); <br />
switch( iResults )<br />
{<br />
case 0:<br />
break;<br />
case SOCKET_ERROR:<br />
break;<br />
default:<br />
rxbytesremaining -= iResults;<br />
temp_rxbuffer += iResults; <br />
if( rxbytesremaining == 0 )<br />
{<br />
temp_rxpacket = (INDEPENDENCER_PKT *)temp_rxbuffer;
if( temp_rxpacket.verifyCRC() )<br />
{<br />
m_TcpClientRxPktCount++;<br />
RxQueue.Push( temp_rxpacket );<br />
}else{<br />
m_TcpClientRxPktCrcErrCount++;<br />
}<br />
}<br />
break;<br />
}
<br />
break;
Scott Dolan
Jernie Corporation
Engineering & Manufacturing
Software, Hardware, & Enclosures
|
|
|
|
|
ScotDolan wrote: You basicly wait for events Once you get a read event you start a thread to handle that event and read the fifo. But, before you start that thread you make sure the past current read thead has terminate.
No actually I'm talking about waiting on events when already in the send/recv thread.
For good throughput using TCP it's important to keep the socket send buffers full and the recv
buffers empty. The socket should never have to wait for the app to receive data from its
buffers otherwise communication stops. Of course, when there's no data to send that's fine -
that means everything's caught up. Using the method below, the thread deals solely with
sending and receiving on the socket. Data to send is queued by another thread, which sets
the datatosendevent. Received data is immediately queued and an event is set indicating to
another thread that data has been received for processing. Those other threads can take as much
time processing as they want - the point is the send/recv thread keeps the data flowing with
minimal waiting. Also, being completely event driven, there's little wasted CPU cycles.
while (1)
{
WaitMultipleObjects() on terminateevent, datatosendevent, socketevent(FD_READ/FD_CLOSE)
if (terminateevent)
break;
if (socketevent)
{
if (FD_CLOSE event)
{
notify app that remote socket closed
break;
}
else
{
loop calling recv() (queueing complete packets)
until WSAWOULDBLOCK error
Notify recv handler thread using an event object when received data available
}
}
if (datatosendevent)
{
dequeue a send packet
loop calling send()
until WSAWOULDBLOCK error or no more queued send data
if WSAWOULDBLOCK and still data on send queue then set datatosendevent
}
}
return (exit thread)
|
|
|
|
|
Assuming it's TCP, why not just resend whatever send() couldn't send? send() returns the number of bytes it managed to send...
--
Verletzen zerfetzen zersetzen zerstören
Doch es darf nicht mir gehören
Ich muss zerstören
|
|
|
|
|
If you want to use TCP, then you must write your code to accommodate partial sends and recvs, and also to accommodate multiple sends and recvs. There is no way around this. TCP is reliable but it's stream-based, not message-based. This means that TCP views the data as a simple stream of singular bytes, and it's up to the appication to decide what the bytes mean. Even if you could somehow check for availability of room in the send buffer, that information is completely unrelated to how the stack will ultimately send data out over the wire, and of course is totally unrelated to how the recipient stack will re-assemble data at the receiving side.
UDP, on the other hand, is message-based. It will definitely preserve "messages" or "packets". However, unlike TCP, UDP is unreliable, in the sense that either the entire message will be delivered, or nothing at all will be delivered.
You need to decide on your requirements.
Mike
|
|
|
|
|
Mike,
From my understanding, all the UDP data grams are recieved into a single recieve FIFO. There is no way within winsock to pull packets out of the buffers. And even if you could pull packets out of buffer, there is no garantee that all the packets are of the same size as application/someone might placed a unexpected packet..
Scott Dolan
Jernie Corporation
Engineering & Manufacturing
Software, Hardware, & Enclosures
|
|
|
|
|
So I am writing a mixed assembly, part of it is managed C++ and part of it is unmanaged. In unmanaged part I'm calling function atan2f( y,x) from <math.h> . it runs in double for loop over whole matrix and takes a very long time to compute. In fact, when I change this code from unmanaged to managed and instead of atan2f call System::Math::Atan2(y,x), I get significant speed gains. Difference is so obvious that I cant process images in real time with atan2f, whilst with Math::Atan2 I can. How is that possible?
Is there any other(faster) way to compute atan2 in unamanaged C++ code?
|
|
|
|
|
The managed version becomes native code as soon as it's run for the first time. Perhaps it's written more efficiently ?
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
i know it becomes native, but it surely can't be that slower. The difference is really huge. I mean, i can't do anything with atan2 from math.h. Surely it can't be implemented that slower. Same goes for log().
|
|
|
|
|
I made a try (C# Math.Atan2 vs C++ atan2 ) and (though I can't believe it) Math.Atan2 seems to be twice faster than atan2 .
I think that needs a further investigation...
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Try using atan2 instead of atan2f . What are the results then?
Steve
|
|
|
|
|
same as atan2f. didn't time it but you can tell by looking at it.
|
|
|
|
|
I'd be interested in seeing the results of a native C++ and managed C++ test programs. Just a simple loop calling atan2 in C++ or the dotNET version for the managed version. Having two seperate simple apps would take a lot of potential causes out of the mix. I thinking perhaps its related to the mixed mode assembly.
Steve
|
|
|
|
|
hi
i need to change the Language (in language bar) every time i set the focus on my Window ( like English to German ). my program is in c#. I thought i should use API to do this. so anybody know such an api Function? or is there another way to do it?
thanks
|
|
|
|
|
hamidreza_buddy wrote: my program is in c#.
So what kept you from here?
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
I said i thought i have to use API. so this is why i asked my question here. i dont think there is a direct way to do such a thing in c#.
|
|
|
|
|
A C# question on the C++ forum
|
|
|
|
|
i must do robot simulation with opengl.i m senior student of electric-electronic engineering and in my greduation work i must control robot arm and its simulation.i dont know anything about opengl if anyone can help me about opengl so i ll be very pleasure.
http://www.pololu.com/products/elenco/0325/
this is my robot arm.
|
|
|
|
|
This[^] is an excellent guide to learn about OpenGL.
|
|
|
|
|
I used a splitter window in my app, which split mainframe into two views (left and right). But I found that CSplitterWnd modifies the right view's size while remains the left one's in default when I drag the left edge of mainframe.
What I need is remaining of the right view's size. I implemented the OnSize func of mainframe, in which I call the SetColumnInfo to fix the right view. However the effect is not so good that you can see the right view flash because MFC modified the size of right view first then you alter it back to the original size in turn. That's bad.
And also I have tried handling WM_SIZE in SplitterWnd. It doesn't work either. The point is that MFC would do it before you receive WM_SIZE.
So, hope you can help me, thanks.
|
|
|
|
|
YUNAJAPAN wrote: However the effect is not so good that you can see the right view flash because MFC modified the size of right view first then you alter it back to the original size in turn.
Are you calling CSplitterWnd::RecalcLayout() on the splitter wnd after using SetColumnInfo() ?
If you are doing the SetColumnInfo/RecalcLayout in the frame's OnSize() then the view pane
shouldn't flash because it doesn't get resized.
|
|
|
|
|
Yes, I did called RecalcLayout.
I placed AfxMessage in SplitterWnd, so you can see what MFC did before it sent WM_SIZE because the GUI would be sticked until the message box return. I found that the view's size has been changed when the box show. Then after your clicking of OK button, the size of view is restored to the original due to SetColumnInfo/RecalcLayout.
I want to find the first place where MFC change the view's size.
Thank you for replying.;)
|
|
|
|
|
You should only need to respond to WM_SIZE in the frame window class of the window containing the
splitter wnd, something like
void CMyFrameWnd::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
pSplitterWnd->SetColumnInfo(...);
pSplitterWnd->RecalcLayout();
}
RecalcLayout() will change the view sizes - you don't need to do that (it happens in
CSplitterWnd::OnSize(), where RecalcLayout() is called again).
You shouldn't be handling WM_SIZE in SplitterWnd unless you are sure to call the base class.
You can also try (in the above example code) getting the client rect and calculating the width
of column 0 (clientrect.Width() - desiredwidthofcolumn1) and using SetColumnInfo() on column 0
instead of column 1. That works for me no problems.
|
|
|
|
|
Perhaps only responding to WM_SIZE in frame is not enough, friend.
I have tried the code above at first (certainly in framewnd), but it flash. If you don't believe that, try this code:
void CMyFrameWnd::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType,cx,cy);
AfxMessageBox("I am a good man");
pSplitterWnd->SetColumnInfo(...);
pSplitterWnd->RecalcLayout();
}
You will see what happened to the splitter bar. It likes these steps:
1. move from right to left;
2. I am a good man;
3. move back to right(the original position).
So step 1 and 3 made it flash. I want to find out a method that MFC don't move the splitter bar.
|
|
|
|
|
Something else is going on then. I use many splitters and have no problem.
Maybe the flash is the way you are redrawing the view?
Having a message box in the WM_SIZE handler is a bad idea
|
|
|
|
|
The things are like this: I make an MFC program in Visual Studio 2005, and the program_name.exe doesn't work on a computer that doesn't have the Visual Studio 2005 installed on it (but it does have Visual Studio .NET 2003). How can I make the program_name.exe work on every computer? How do I make an install file for my program?
Thanks
|
|
|
|