|
Oy....
Ok, I've confused you guys. That ToString() function doesn't exist yet.
This is what I'm trying to do:
WCHAR text[] = L"3/4";
swprintf_s(text, 4, L"%c/%c", m_CurrentPage, m_NumPages);
to change text to L"1/2".
|
|
|
|
|
If I have a *.lib file and corresponding header files how can I create a DLL? Any ideas? I don't have access to the source code. I have been told that I can create the dll using the lib file, but not sure quite where to go. Am I right in thinking I'll have to write some code to 'wrap' the lib file?
|
|
|
|
|
Yes. You need to 'wrap' each function in the LIB you want exposed from the DLL.
Or you can make a 'higher level' interface to the library by aggregating function callss into easier to use constructs of action, for example.
|
|
|
|
|
I have a client and a server. The server can accept only 2 connections. The client is written with VC++ and the server is written in C++.
Client:
<br />
...<br />
result = mySck.Connect(ip address, port number);<br />
if (!result)<br />
{<br />
...<br />
}<br />
else<br />
{<br />
...<br />
}<br />
Server:
<br />
#define QUEUE_SZ 0<br />
...<br />
...<br />
result = listen(svr_sck, QUEUE_SZ);<br />
...<br />
Worker thread:
<br />
#define MAX_SCKS 2<br />
int totoal_scks = 0;<br />
<br />
while(1)<br />
{<br />
if (total_scks < MAX_SCKS)<br />
{<br />
printf("Ready to accept connection");<br />
tmpSck = accept(svr_sck, (struct sockaddr *) &stClntAddr, &sckAddrSize);<br />
if (tmpSck == ERROR)<br />
{<br />
...<br />
}<br />
else<br />
{<br />
total_scks++;<br />
...<br />
}<br />
}<br />
else<br />
{<br />
...<br />
}<br />
}<br />
There is more to the code but this should do for now.
After I connect 2 clients, the server no longer prints that it is ready to accept connections. This means that I am not executing the accept statement a 3rd time. This is what I am expecting.
The problem is:
However when I try to connect a 3rd client, it looks like the server still accepts the connection but I am not executing the code after the accept statement and total_scks is still 2. On the client side the Connect function returns 1 which means that the connection was successful. How can this happenned?
If QUEUE_SZ is 0, I can connect a 3rd connection but on the 4th, the Connect function returns 0. If QUEUE_SZ is 1, I can connect a 3rd and a 4th connections but on the 5th, Connect returns 0...and so on.
Anybody can help me with this?
jpyp
|
|
|
|
|
IMO you left out the most important parts of code in your post - the creation of the sockets.
There's two things going on here, but I can only help with one since you left the rest out.
jpyp wrote: If QUEUE_SZ is 0, I can connect a 3rd connection but on the 4th, the Connect function returns 0.
If QUEUE_SZ is 1, I can connect a 3rd and a 4th connections but on the 5th, Connect returns 0...and so on.
The backlog parameter of the listen() function sets the maximum number of pending connections.
That's how many connections will sit queued until you accept or refuse them. When the queue
is full, additional incoming connections should be immediately refused.
I'm not sure what the behavior is when you set this to 0. Regardless, since you allow two
simultaneous connections, you might as well set this to at least 2 and refuse connections some
other way.
As for the unknowns, what protocol are you using? How are you creating the sockets?
Assuming TCP then it gets a little tricky rejecting connections with Winsock because of security
issues related to SYN attacks (thank the idiot "hackers").
Based on the code you've shown, I would expect the 3rd client's Connect() call to block until
it times out. If you put a breakpoint on the accept() call in the server, it should only get
called twice with 3 connection attempts, correct?
|
|
|
|
|
You are correct. Because of my total_scks counter, accept() only gets called twice. However since I got your reply I found a little more info from the Tornado help docs. I now understand a lot better what is going on and I suspect a lot of people do not know this:
The queue size parameter in listen() does not affect the number of simultaneous connections that the server will accept. You need a counter like I have implemented to restrict the number of simultaneous connections. In my case if I already have 2 connections and I have 5 for queue size as parameter to the listen() function, then the server will queue up to 5 new clients. Once one of the current connections closes, the first queued client will then be accepted.
What I now understand is that listen() actually makes the connection with the client, not accept(). Therefore if you have a counter of 2 and a queue of 5, you could actually have 7 clients connected at once but only 2 of these will be accepted and transfering data. The connect() function on the clients that are queued returns successful because listen() on the server made the connection.
This last point is very interesting and brings me to my next question:
How can I detect on the client that the connection is not yet accepted by the server or that I lost the connection with the server?
Thanks for your help?
jpyp
|
|
|
|
|
//jpyp wrote: The queue size parameter in listen() does not affect the number of simultaneous connections that the server will accept
That's what I meant
For TCP here's how I found to do it. If someone else jumps in with a better solution I'd like to
see it!!
WSAAccept() is the only accept function that allows you to refuse a connection. BUT, with TCP/IP
the connection has to be made to prevent SYN attacks. WSAAccept() will immediately close the
socket though if you refuse the connection. What I do is try a send() of 0 bytes on the client
right after I connect. It will fail if the server refused the connection.
Here's an example (I altered the worker thread a bit so you wouldn't have to do the Sleep() a
little and loop thing)...
Initialize before worker thread runs:
<small>
...
hTerminateEvent = ::CreateEvent(NULL, false, false, NULL);
hNetEvent = ::CreateEvent(NULL, true, false, NULL);
::WSAEventSelect(svr_sck, hNetEvent, FD_ACCEPT);</small>
Worker thread proc:
<small>while (1)
{
#define EVENT_NET 0
#define EVENT_TERMINATE 1
HANDLE Events[] =
{
hNetEvent,
hTerminateEvent
};
DWORD dwEventIndex = ::WaitForMultipleObjects(sizeof(Events) / sizeof(HANDLE),
Events, FALSE, INFINITE);
if (dwEventIndex == WAIT_FAILED)
{
break;
}
dwEventIndex -= WAIT_OBJECT_0;
if (dwEventIndex == EVENT_TERMINATE)
{
break;
}
if (dwEventIndex == EVENT_NET)
{
WSANETWORKEVENTS WsaNetworkEvents;
if (0 == ::WSAEnumNetworkEvents(svr_sck, hNetEvent, &WsaNetworkEvents))
{
if (WsaNetworkEvents.lNetworkEvents & FD_ACCEPT)
{
sockaddr SockAddr;
int SockAddrLen = sizeof(sockaddr);
SOCKET hSocket = ::WSAAccept(svr_sck, &SockAddr, &SockAddrLen,
AcceptConditionProc, (DWORD_PTR)tal_scks);
if (hSocket != INVALID_SOCKET)
{
...
total_scks++;
}
}
}
}
}
::ExitThread(0U);
return 0U;
AcceptConditionProc():
<small>int CALLBACK AcceptConditionProc(LPWSABUF lpCallerId,
LPWSABUF lpCallerData,
LPQOS lpSQOS,
LPQOS lpGQOS,
LPWSABUF lpCalleeId,
LPWSABUF lpCalleeData,
GROUP FAR * g,
DWORD_PTR dwCallbackData)
{
int ConnectionCount = (int)dwCallbackData;
if (ConnectionCount < MAX_SCKS)
{
return CF_ACCEPT;
}
return CF_REJECT;
}</small>
On the client:
<small>
...
result = mySck.Connect(ip address, port number);
if (!result)
{
...
}
else
{
int err = 0;
int sockret = ::send(mySck.m_hSocket, (const char *)&err, 0, 0);
if (sockret == SOCKET_ERROR)
{
err = ::WSAGetLastError();
mySck.Close();
TRACE1( "** Connection refused by server (::send() 0 bytes returned errcode %li)\n", err);
return;
}
}</small>
*EDIT* formatted the code a bit
|
|
|
|
|
Thanks a lot. This is exactly what I was looking for.
jpyp
|
|
|
|
|
How can i in c++ (or with mfc) how can i detect if mouse button three is down? ( the scroll wheel button being pressed)
like this:
while(true)
{
while(MBUTTON3 == DOWN)
{
//executed when down
}
}
thanks
/Johannes
|
|
|
|
|
Johpoke wrote: while(MBUTTON3 == DOWN)
Are you looking for WM_MBUTTONDOWN ?
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Yea kinda, i know of that, as ive used while left button down, but i cant find out how to do while scroll wheel down...
/Johannes
|
|
|
|
|
Johpoke wrote: ive used while left button down...
Why would you be using WM_MBUTTONDOWN with the left mouse button?
Johpoke wrote: but i cant find out how to do while scroll wheel down...
What about WM_MOUSEWHEEL ?
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
He said MBUTTON, not LBUTTON right?
Check this out: About Mouse Input[^]
especially the section "The Mouse Wheel"
|
|
|
|
|
Yea thats it, i need to use these;
WM_MBUTTONDOWN //The middle mouse button was pressed.
WM_MBUTTONUP //The middle mouse button was released.
i read at http://msdn2.microsoft.com/en-us/library/ms645601.aspx
but i cant find out how to use it.. it needs windows.h, but what else do i need to do? so that this can work:
while(true)
{
while(WM_MBUTTONDOWN == TRUE)
{
//does when it down
}
}
thanks
EDIT: its important that it works globaly, so i can have this minimized and im working in another app and it should still detect it
/Johannes
|
|
|
|
|
Johpoke wrote: but i cant find out how to use it.. it needs windows.h, but what else do i need to do?
Uh oh. Have you written a windows app yet? WM_MBUTTONDOWN is a message sent by the system to
the window with focus. How you respond to this message in code is different with straight C/C++
than MFC. Maybe you have some studying to do??
|
|
|
|
|
Uh oh, well i havent done any of the programing yet, ille do that part when i know i can get this to work, so for me it doesnt matter if its mfc, win32, win32 console or anything.. just as long as its c++... is it hard to detect middle mouse globaly?
/Johannes
|
|
|
|
|
Johpoke wrote: is it hard to detect middle mouse globaly?
"hard" is relative. I imagine it's hard if you've never written a windows app before.
An understanding of Windows messaging is necessary for sure
|
|
|
|
|
ah sounds like ille have to ditch that idea..
thanks anyway
/Johannes
|
|
|
|
|
You can trap the WM_MBUTTONDOWN and WM_MBUTTONUP messages or you can use the GetAsyncKeyState() function.
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
|
My app has a main dialog window. By using PreTranslateMessage() it looks for pressed keys. When a certain key is pressed and held down a popup dialog window appears. When the key is released the window is supposed to close but it doesn't.
The code works in such way that as long as the key is pressed an if-statement is true. In the statement there is a
m_dlgMenu.ShowWindow(SW_SHOW);
which shows the popup dialog.
When the key is released the if-statement is false and a
m_dlgMenu.ShowWindow(SW_HIDE);
is called to close the popup.
The problem is that the popup window isn't closed until the mouse is moved. What may be the reason for this? It seems like it waits for a message before the popup is closed.
Thanks for any help!
|
|
|
|
|
Can you post your PreTranslateMessage() code?
Where is this "if-statement" you speak write of?
|
|
|
|
|
Actually I made a simplification when I described the problem. The PreTranslateMessage() checks for a TAB-keypress and as long as TAB is held down it calls CCameraControlDlg::ManualMode()
The CCameraControlDlg is the main dialog.
BOOL CCameraControlDlg::PreTranslateMessage(MSG* pMsg) <br />
{<br />
<br />
if (GetAsyncKeyState(VK_TAB) < 0) { <br />
CCameraControlDlg::ManualMode();<br />
}<br />
Sleep(10);<br />
return CDialog::PreTranslateMessage(pMsg);<br />
<br />
}
In the CCameraControlDlg::ManualMode() function there are again and if-statement. This look for F2-keypresses as shown below. As long F2 is held down it calls the MouseScroll-function which is used for scrolling up and down a menu in the other dialog. Then m_dlgMenu.ShowWindow(SW_SHOW) are used to show the other dialog. When the F2-key is released the other if-statement will be true and should hide the window. But nothing happens until the mouse is moved (the TAB-key is still pressed).
<br />
void CCameraControlDlg::ManualMode() {<br />
.<br />
.<br />
.<br />
<br />
if ((GetAsyncKeyState(VK_F2) < 0) && ((control_nr == 2) || (control_nr == 0))) { <br />
<br />
x_F2 = MouseScroll(menu_roof, reset_val);<br />
<br />
m_dlgMenu.ShowWindow(SW_SHOW);<br />
m_dlgMenu.m_strHeader.Format("White Balance");<br />
m_dlgMenu.m_strChoice.Format(menu_text_F2[x_F2]);<br />
<br />
m_dlgMenu.UpdateData(FALSE); <br />
<br />
control_nr = 2;<br />
<br />
}<br />
<br />
else if (control_nr == 2) {<br />
<br />
m_dlgMenu.ShowWindow(SW_HIDE)<br />
control_nr = 0;<br />
}<br />
<br />
.<br />
.<br />
.<br />
}<br />
Another thing is that it works as expected if the style of the other dialog is set to "child" instead of "popup" but when F2 is held down the dialog flickers a couple of times before it is shown , which is annoying. This is not the case when the style is "popup".
Thanks for your help
|
|
|
|
|
Hehe, got it to work
I placed a PreTranslateMessage() in the code for the other dialog and it called OnOK() when GetAsyncKeyState(VK_F2) == 0
|
|
|
|
|
hi , i m new n i just managed one clinet server prg but i am not able to connect multiple client to my server.
|
|
|
|