|
Hi Guys,
This is an issue from client. They have a server application & client applications connected to it from different PC's. Both applications are developed in mfc's using socket class.
Server application creates a socket connection & listens to the particular port, server & client sends msg in-between on time interval. Application has been running well for the past year & suddenly the client say that they can't have new client connections connected to the server but old connections are alive. This occurs randomly once in a week or so, once they restart the server application, everything works fine again.
There is no error log for this & couldn't replicate the same problem from work place.
Please suggest me the possible reason why this is happening?
Note:
Server has a socket accept() function which is in while loop waiting for new connection event. When connection arrives, it calls accept function When there is an INVALID_SOCKET error, it closes the socket. Can something go wrong suddenly? is this can be due to network, firewall, router, etc?
Thank you
Mohan
|
|
|
|
|
mohanrajh wrote: suddenly the client say that they can't have new client connections connected
Where does this statement come from, more details would be appreciated... e.g. which socket call reports error, is it a client or a server problem, which part of the application reports error?
-- modified at 6:39 Sunday 25th June, 2006
|
|
|
|
|
Hi,
Why hPrevInstance paramter in WinMain is made to NULL in 32-bit windwos ???
Is there any specific reason ??
Thanks
Appu..
"If you judge people, you have no time to love them."
|
|
|
|
|
This is what the docs say in context to hPrevInstance (MSDN):
The hPrevInstance parameter is always passed NULL in Win32. This causes each instance of an application to act as though it were the only instance running. The application must register the window class, and it cannot access data used by other instances, except through standard interprocess communication techniques such as shared memory or DDE. Calls to GetInstanceData must be replaced with these techniques.
Before registering a window class, source code for Windows 3.x normally tests hPrevInstance to see whether another instance of the application is already running. This code needs no change, because under Win32, it will always register the window class.
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
_AnShUmAn_ wrote: Before registering a window class, source code for Windows 3.x normally tests hPrevInstance to see whether another instance of the application is already running
So , In 16 - bit Windows there is no registration of window class. Which was introduced in Win 32 ,which lets us know about the Previous Instance of an application.. Am I right ??
I have few more doubts ..
When we run an application for the first time the window class gets registered.
suppose if second instance of application is created .will the registration of the class takes place again ??
if so, Is the registered class name same as that of first instance.
_AnShUmAn_ wrote: The hPrevInstance parameter is always passed NULL in Win32. This causes each instance of an application to act as though it were the only instance running
Can u explain this in more detail ???
Any how , Thanks a lot for u r reply.
Thanks again.
Appu..
"If you judge people, you have no time to love them."
|
|
|
|
|
My previous post included this :
(Read about this in MSDN)
Before registering a window class, source code for Windows 3.x normally tests hPrevInstance to see whether another instance of the application is already running. This code needs no change, because under Win32, it will always register the window class.
And regarding your question here :Is the registered class name same as that of first instance?
I haven't thought on this issue. But may be I will do it now and get back to you if somebody else doesn't clarify on this.Guess, it should register itself for the first time.
2nd Answer:
Applications cannot use hPrevInstance to test for previous instances under Win32. An alternative method must be used, such as creating a unique named pipe, creating or testing for a named semaphore, broadcasting a unique message, or calling FindWindow.
I hope that this satisfies your queries.
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
|
Thanks Anshuman and FarPointer.
Those who are looking for the same Question, Here is the reason.
Once your average GUI program picks itself up off the ground, control begins at your WinMain function. The second parameter, hPrevInstance, is always zero in Win32 programs. Certainly it had a meaning at some point?
Of course it did.
In 16-bit Windows there was a function called GetInstanceData. This function took an HINSTANCE, a pointer, and a length, and copied memory from that instance into your current instance. (It's sort of the 16-bit equivalent to ReadProcessMemory, with the restriction that the second and third parameters had to be the same.)
(Since 16-bit Windows had a common address space, the GetInstanceData function was really nothing more than a hmemcpy, and many programs relied on this and just used raw hmemcpy instead of using the documented API. Win16 was actually designed with the possibility of imposing separate address spaces in a future version - observe flags like GMEM_SHARED - but the prevalence of tricks like hmemcpy'ing your previous instance reduced this potential to an unrealized dream.)
This was the reason for the hPrevInstance parameter to WinMain. If hPrevInstance was non-NULL, then it was the instance handle of a copy of the program that is already running. You can use GetInstanceData to copy data from it, get yourself up off the ground faster. For example, you might want to copy the main window handle out of the previous instance so you could communicate with it.
Whether hPrevInstance was NULL or not told you whether you were the first copy of the program. Under 16-bit Windows, only the first instance of a program registered its classes; second and subsequent instances continued to use the classes that were registered by the first instance. (Indeed, if they tried, the registration would fail since the class already existed.) Therefore, all 16-bit Windows programs skipped over class registration if hPrevInstance was non-NULL.
The people who designed Win32 found themselves in a bit of a fix when it came time to port WinMain: What to pass for hPrevInstance? The whole module/instance thing didn't exist in Win32, after all, and separate address spaces meant that programs that skipped over reinitialization in the second instance would no longer work. So Win32 always passes NULL, making all programs believe that they are the first one.
And amazingly, it actually worked.
Thanks friends.
Appu..
"If you judge people, you have no time to love them."
|
|
|
|
|
Hi,
I think I experienced the issue described here with one of my classes :
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.15
I realized that my static member ConfigManager::ConfigFile isn't initialized when I first call a static member function ConfigManager::GetConfigString using it. Could you have a look at my code below and suggest something to avoid this. I'm not really happy with the solution from the faq because it uses "new" to create an object instance that I can't "delete" because my class is static (no destructor).
Thanks !
ConfigManager.h
<br />
#pragma once<br />
<br />
#define DEFAULT_PROFILE CString("C:\\default.ini")<br />
#define DEFAULT_INT -1<br />
#define DEFAULT_STRING CString("");<br />
<br />
class ConfigManager<br />
{<br />
public:<br />
static CString GetConfigFile();<br />
static void SetConfigFile(CString& p);<br />
static void SetConfig(CString section, CString key, CString value);<br />
static CString GetConfigString(CString section, CString key, CString def = DEFAULT_STRING);<br />
static int GetConfigInt(CString section, CString key, int def = DEFAULT_INT);<br />
<br />
private:<br />
static CString ConfigFile;<br />
};<br />
ConfigManager.cpp
<br />
#include "StdAfx.h"<br />
#include "ConfigManager.h"<br />
<br />
CString ConfigManager::ConfigFile = DEFAULT_PROFILE;<br />
<br />
void ConfigManager::SetConfig(CString section, CString key, CString value)<br />
{<br />
WritePrivateProfileString(section, key, value, ConfigManager::ConfigFile);<br />
}<br />
<br />
CString ConfigManager::GetConfigString(CString section, CString key, CString def)<br />
{<br />
CString result(_T(" "),512);<br />
GetPrivateProfileString(section, key, def, result.GetBuffer(), 512, ConfigManager::ConfigFile);<br />
result.ReleaseBuffer();<br />
return result;<br />
}<br />
<br />
int ConfigManager::GetConfigInt(CString section, CString key, int def)<br />
{ <br />
return GetPrivateProfileInt(section, key, def, ConfigManager::ConfigFile);<br />
}<br />
<br />
CString ConfigManager::GetConfigFile()<br />
{<br />
return ConfigManager::ConfigFile; <br />
}<br />
<br />
void ConfigManager::SetConfigFile(CString& p)<br />
{<br />
ConfigManager::ConfigFile = p;<br />
}<br />
|
|
|
|
|
Do you get the same behaviour if you use
CString ConfigManager::ConfigFile(DEFAULT_PROFILE);
instead?
Steve S
Developer for hire
|
|
|
|
|
Steve S wrote: CString ConfigManager::ConfigFile(DEFAULT_PROFILE);
Just tried this, there no change. ConfigManager::ConfigFile is not initialized upon first call... then later upon second call it is.
|
|
|
|
|
Hmm. Is your call to the appropriate ConfigManager member from another static object?
Steve S
Developer for hire
|
|
|
|
|
I don't have an answer to your problem but may I ask why you are using static methods only ? Maybe a singleton pattern is more suited to your needs ? (You'll have only one instance of the class).
I don't really see the advantage of using only static members.
Cédric Moonen
Software developer
Charting control
|
|
|
|
|
Cedric Moonen wrote: I don't really see the advantage of using only static members
logical grouping...
in the .NET framework for instance, you have the Math class which provides only static members/functions, like square root, cosine, logarithm, etc...
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
|
|
|
|
|
toxcct wrote: logical grouping...
Why not use namespace for that ?
Cédric Moonen
Software developer
Charting control
|
|
|
|
|
in C++ yes... but in general OOP concepts, i'm not sure every languages know what a namespace is, unless classes scopes.
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
|
|
|
|
|
toxcct wrote: in C++ yes
But we are on a C++ board right ?
Cédric Moonen
Software developer
Charting control
|
|
|
|
|
Cedric Moonen wrote: But we are on a C++ board right
oops, you're right, i thought a moment that we were in the lounge...
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
|
|
|
|
|
Cedric Moonen wrote: I don't really see the advantage of using only static members.
Well every method of my class is standalone, it doesn't need any prerequisite to deliver a result. For me the point in having a class instance is to expect a behaviour depending on the past life of the instance. Here I don't think I need to create any (even a single) instance of the class.
Eventually I'll try your idea because it is more likely to work but I think it is simplier and nicer to have ConfigMananger::GetConfigString(....) rather than ConfigManager::GetInstance()->GetConfigString(...)
|
|
|
|
|
Yes, but... Why use a class then ?
Ok, I know that you don't want to use global functions maybe but it's still clearer to declare an instance of your class first and then use the functions. Don't you think ? Otherwise, this doesn't make a lot of sense.
Cédric Moonen
Software developer
Charting control
|
|
|
|
|
Cedric Moonen wrote: Yes, but... Why use a class then ?
Just to gather things that deal with the same subject...
|
|
|
|
|
If your ConfigFile value isn't ever going to be changed, then you can do this
class ConfigManager
{
.
.
.
private:
static const CString ConfigFile = DEFAULT_PROFILE;
};
|
|
|
|
|
Weiye Chen wrote: private: static const CString ConfigFile = DEFAULT_PROFILE;
this is not allowed in C++ (you are showing a C# solution)
he must initialize its static member outise of the class
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
|
|
|
|
|
toxcct wrote: this is not allowed in C++ (you are showing a C# solution)
he must initialize its static member outise of the class
Right,
Moreover I'd like to be able to change the ConfigFile.
|
|
|
|
|
You could put the constant in an anonymous namespace at the top of your implementation file, rather than in the class. You could also have GetConfigFile() set the file name if it hasn't been set, and always call it, rather than use the filename directly - that way it would always be initialised before it was used
Cedric is right though. Since your class contains state, it is better implemented as a singleton, rather than a bunch of static methods and a static data member.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|