|
Vladimir
You are not doing this the right way at all.
You are calling GetSockName() on an unconnected socket. That will result in weird results. I suggest that you seriously take up a book and just browse through the basic. It should take you only 10-20 mins to get adjusted to it.
And one piece of advice :- The MFC socket classes are not thread-safe and you can run into all sorts of trouble using them. As far as possible use the native Winsock API.
Nish
It's seven o'clock
On the dot
I'm in my drop top
Cruisin' the streets - Oh yeah
I got a real pretty, pretty little thing that's waiting for me
|
|
|
|
|
Nish [BusterBoy] wrote:
And one piece of advice :- The MFC socket classes are not thread-safe and you can run into all sorts of trouble using them. As far as possible use the native Winsock API.
This is sort of true, sort of not true. The MFX Socket classes don't work very well multi threaded. But they do work.
However, looks to me like you'd be far better off staying single threaded, but using CAsyncSocket.
Sorry to dissapoint you all with my lack of a witty or poignant signature.
|
|
|
|
|
All the traces lead to this piece of code:
// The same socket better not be blocking in more than one place.
ASSERT(m_pbBlocking == NULL);
_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
ASSERT(pState->m_hSocketWindow != NULL);
BOOL bBlocking = TRUE;
m_pbBlocking = &bBlocking;
CWinThread* pThread = AfxGetThread();
in a socketsomething.cpp
"Needless redundancy is the hobgoblin of software engineering." - Peter Darnell
|
|
|
|
|
ASSERT(pState->m_hSocketWindow != NULL);
this assertion failed... If you can think of something, please post it.
"Needless redundancy is the hobgoblin of software engineering." - Peter Darnell
|
|
|
|
|
g_sListen.Create(0);
g_sListen.GetSockName(s_name, port);
g_sListen.Bind(port);
g_sListen.Listen();
Nish
It's seven o'clock
On the dot
I'm in my drop top
Cruisin' the streets - Oh yeah
I got a real pretty, pretty little thing that's waiting for me
|
|
|
|
|
Hmm, I think the sequence here should be:
g_sListen.Create(0);
g_sListen.Bind(....);
g_sListen.GetSockName();
You can pass NULL to Bind, and let system give you the IP address of local computer as well as assign a free port number to you. Since both are assigned by the system, you want to call GetSockName to retrieve these two parameters.
|
|
|
|
|
In my dialog app i have 2 functions which use ADO connection to catch value from a database, and which put them into a "C" pointer of pointer and a regular pointer. I want after in a third function use the 2 pointers, which represent some of the input data. As i do it with 3 different button which each of them call one and only one function.
For example the first, called OnLoadCorrel, put a whole matrix into a **pCorrel, the second one called On LoadVol, put a whole array into a *pVol. And, finally, the 3 function use the values needed coming from the matrix and the array. It's at this point of my app that there's a pb, because when i call the third function, the app doesn't recognize (or know) the value into both the pointers (perhaps the value have been lost?!?)
So you could see the following lost, and i hope that soeone could find if what is wron in my app.
/////////////////////////////////////////////////////////
So, in the CalcRiskPortDlg.cpp::
void CCalcRiskPortDlg::OnLoadVol()
{
UpdateData(TRUE);
::CoInitialize(NULL);
LoadTables Table(m_dlgSector);
int i;
// _variant_t IndexCol;
CString strValue;
try
{
_ConnectionPtr pConnection=NULL;
CString strTemp;
strTemp.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\CalcRiskPort\\vol_correl1.mdb;");
_bstr_t strCnn(strTemp);
TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
pConnection->Open(strCnn,"","",adConnectUnspecified);
_RecordsetPtr pTp("ADODB.Recordset");
try
{
pTp->Open("Volatilité",strCnn,adOpenStatic,adLockOptimistic,adCmdTableDirect);
if(!pTp->EndOfFile)
{
for(i=1;i<=m_dlgSector;i++)
{
pTp->MoveFirst();
pTp->Move(i-1);
//strIndexCol=Table.ConvIntToVar((double)j);
//strIndexCol=strIndexCol+strT;
//_variant_t IndexCol(strIndexCol);
*(Table.pVol+i)=pTp->Fields->GetItem("Volatilité")->Value;
}
}
//dValue=pTp->Fields->GetItem("N° Titre")->Value;
//Parameter2=pTp->Fields->GetItem(IndexColumn)->Value;
pTp->Close();
}
catch(_com_error &e)
{
AfxMessageBox("a pas bon");
}
m_dlgValue=Table.pVol[3];
strValue.Format("%.9f",m_dlgValue);
CEdit* PEdit=(CEdit*)GetDlgItem(IDC_VALUE);
PEdit->SetWindowText(strValue);
//Table.free_dmatrix(Table.pCorrel,1,m_dlgPortWeight,1,m_dlgPortWeight);
pConnection->Close();
}
catch(_com_error &e)
{
AfxMessageBox("a pas bon");
}
::CoUninitialize();
// TODO: Add your control notification handler code here
}
void CCalcRiskPortDlg::OnLoadCorrel()
{
UpdateData(TRUE);
::CoInitialize(NULL);
LoadTables Table(1,m_dlgSector,1,m_dlgSector);
int i,j;
// _variant_t IndexCol;
CString strValue,strT,strIndexCol;
strT="t";
//Table.pCorrel=Table.dmatrix(1,m_dlgPortWeight,1,m_dlgPortWeight);
try
{
_ConnectionPtr pConnection=NULL;
CString strTemp;
strTemp.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\CalcRiskPort\\vol_correl1.mdb;");
_bstr_t strCnn(strTemp);
TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
pConnection->Open(strCnn,"","",adConnectUnspecified);
_RecordsetPtr pTp("ADODB.Recordset");
try
{
pTp->Open("Correlation",strCnn,adOpenStatic,adLockOptimistic,adCmdTableDirect);
if(!pTp->EndOfFile)
{
for(i=1;i<=m_dlgSector;i++)
{
for(j=1;j<=m_dlgSector;j++)
{
pTp->MoveFirst();
pTp->Move(i-1);
strIndexCol=Table.ConvIntToVar((double)j);
strIndexCol=strIndexCol+strT;
_variant_t IndexCol(strIndexCol);
*(*(Table.pCorrel+i)+j)=pTp->Fields->GetItem(IndexCol)->Value;
}
}
}
//dValue=pTp->Fields->GetItem("N° Titre")->Value;
//Parameter2=pTp->Fields->GetItem(IndexColumn)->Value;
pTp->Close();
}
catch(_com_error &e)
{
AfxMessageBox("a pas bon");
}
m_dlgValue=Table.pCorrel[3][7];
strValue.Format("%.9f",m_dlgValue);
CEdit* PEdit=(CEdit*)GetDlgItem(IDC_VALUE);
PEdit->SetWindowText(strValue);
//Table.free_dmatrix(Table.pCorrel,1,m_dlgPortWeight,1,m_dlgPortWeight);
pConnection->Close();
}
catch(_com_error &e)
{
AfxMessageBox("a pas bon");
}
::CoUninitialize();
// TODO: Add your control notification handler code here
}
void CCalcRiskPortDlg::OnCalcvar()
{
UpdateData(TRUE);
::CoInitialize(NULL);
LoadTables Table;
double Var;
double *pTabVar=new double[pow(2,m_dlgSector)];
CString strValue;
int *pTabBinPort=new int[m_dlgAsset];
int *pTabNumPort=new int[m_dlgAsset];
int k,i;
i=0;
for(k=0;k<=m_dlgAsset-1;k++)
{
*(pTabBinPort+k)=0;
Table.ConvertBinToNum(k,pTabBinPort,pTabNumPort);
}
*pTabVar=Table.CalcVar(pTabNumPort,m_dlgAsset);
for(i=1;i<=pow(2,m_dlgSector);i++)
{
k=m_dlgSector-1;
while(*(pTabBinPort+k)==1)
{
*(pTabBinPort+k)=0;
Table.ConvertBinToNum(k,pTabBinPort,pTabNumPort);
k--;
}
*(pTabBinPort+k)=1;
Table.ConvertBinToNum(k,pTabBinPort,pTabNumPort);
*(pTabVar+i)=Table.CalcVar(pTabNumPort,m_dlgAsset);
}
m_dlgValue=pTabVar[2];
strValue.Format("%.9f",m_dlgValue);
CEdit* PEdit=(CEdit*)GetDlgItem(IDC_VALUE);
PEdit->SetWindowText(strValue);
delete []pTabVar;
delete []pTabNumPort;
delete []pTabBinPort;
::CoUninitialize();
// TODO: Add your control notification handler code here
}
///////////////////////////////////////////////////////////
and for information the LoadTable.cpp code where you could find others function's definitions:
#include "stdafx.h"
#include "CalcRiskPort.h"
#include "LoadTables.h"
#define NR_END 1
#define FREE_ARG char*
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
LoadTables::LoadTables()
{
}
LoadTables::LoadTables(long a,long b,long c,long d)
{
//free_dmatrix(pCorrel,a,b,c,d);
pCorrel=dmatrix(a,b,c,d);
}
LoadTables::LoadTables(long a)
{
pVol=NULL;
Delete_pVol();
pVol=new double [a];
}
void LoadTables::Delete_pVol()
{
if(pVol!=NULL)
{
delete[] pVol;
pVol=NULL;
}
}
LoadTables::~LoadTables()
{
}
void LoadTables::nrerror(char error_text[])
{
AfxMessageBox("Ca marche moyen");
exit(1);
}
double **LoadTables::dmatrix(long LowRow,long HighRow,long LowCol,long HighCol)
{
long i, RowSize=HighRow-LowRow+1,ColSize=HighCol-LowCol+1;
double **m;
m=(double **)malloc((size_t)((RowSize+NR_END)*sizeof(double*)));
if(!m)nrerror("pb allocation1 in matrix()");
m +=NR_END;
m -=LowRow;
m[LowRow]=(double *)malloc((size_t)((RowSize*ColSize+NR_END)*sizeof(double)));
if(!m[LowRow])nrerror("pb allocation2 in matrix()");
m[LowRow] +=NR_END;
m[LowRow] -=LowCol;
for(i=LowRow+1;i<=HighRow;i++)
m[i]=m[i-1]+ColSize;
return m;
}
void LoadTables::free_dmatrix(double **m,long LowRow,long HighRow,long LowCol,long HighCol)
{
free((FREE_ARG)(m[LowRow]+LowCol-NR_END));
free((FREE_ARG)(m+LowRow-NR_END));
}
CString LoadTables::ConvIntToVar(double j)
{
CString strIndexCol;
int decimal,sign;
strIndexCol=_fcvt(j,0,&decimal,&sign);
//_variant_t IndexCol(strIndexCol);
return strIndexCol;
}
double LoadTables::ReturnValue(long Row,_variant_t IndexCol, _variant_t ParamTable)
{
double dValue;
CString strTemp;
strTemp.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\CalcRiskPort\\vol_correl1.mdb;");
_bstr_t strcnn(strTemp);
_RecordsetPtr pTp("ADODB.Recordset");
try
{
pTp->Open(ParamTable,strcnn,adOpenStatic,adLockOptimistic,adCmdTableDirect);
pTp->MoveFirst();
pTp->Move(Row-1);
if(!pTp->EndOfFile)
dValue=pTp->Fields->GetItem(IndexCol)->Value;
//dValue=pTp->Fields->GetItem("N° Titre")->Value;
//Parameter2=pTp->Fields->GetItem(IndexColumn)->Value;
pTp->Close();
}
catch(_com_error &e)
{
AfxMessageBox("Table non atteinte");
pTp->Close();
}
return dValue;
}
double LoadTables::CalcVar(int* pTabNumPort,int NbOfAsset)
{
int i,j;
double sum1,sum2,sum;
sum=sum1=sum2=0;
for(i=1,j=0;i<=NbOfAsset,j
|
|
|
|
|
Hi,
I want to create a Winpopup type in VC Dialog Based one.
How to send a message from one system to anothere system.
Regards,
Mani.
|
|
|
|
|
Does anyone know of a way to guard a delete operator from trying to release a non-allocated block, as in the following trivial example.
short x[ 100 ];
try
{
delete []x;
}
catch( ... )
{
return MDERROR;
}
This does not work as the exception is caught somewhere in the bowels of the system and I get either an assert or a user breakpoint box. I have looked at RTTI but it doesn't help me. How can I prevent a crash if I'm passed a pointer to a global or static block?
Thanks all!
|
|
|
|
|
This function determines whether a given pointer belongs in the stack or not:
bool is_stack_memory(void * p)
{
char check;
MEMORY_BASIC_INFORMATION m1,m2;
::ZeroMemory(&m1,sizeof(m1));
::ZeroMemory(&m2,sizeof(m2));
::VirtualQuery(p,&m1,sizeof(m1));
::VirtualQuery(&check,&m2,sizeof(m2));
return m1.BaseAddress==m2.BaseAddress;
} So you can write code like
if(is_stack_memory(x)){
printf("x has not been dynamically allocated\n");
return MDERROR;
}
else{
delete [] x;
} Anyway, IMHO designing functions around this feature is not a very good idea. I'd restrict the ability to determine whether a pointer is delete able to doing error checking in debug mode.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
PS: There's a limitation in is_stack_memory , namely that it fails to identify pointers on other threads' stacks. This could be worked around, however.
|
|
|
|
|
or, if you ALWAYS init pointers to NULL, and ALWAYS reset them to NULL after delete, like I do, then:
if (pointer)
delete [] pointer;
pointer = NULL;
Sorry to dissapoint you all with my lack of a witty or poignant signature.
|
|
|
|
|
If I were you, I would review my design. By this I mean that an object shouldn't deallocate memory it didn't allocate (which is obviously the case here since your object can't figure out if it is stack or heap memory), unless you have a good reason.
If I am wrong or said something stupid, I apologize in advance
Michel
|
|
|
|
|
Thanks for your thoughts. I didn't design or write this stuff. I'm only trying to wrap an audio interface I got pre-cooked. I watch my own new's and delete's like a hawk and always have the leakage detector on.
The bit about nulling the pointer is very good (simple and obvious) and will be standard in my code from now on.
I do however find it strange that delete doesn't throw a catchable exception. There must be a good reason for it. I will try it on Linux and see if it tells me why.
|
|
|
|
|
Hi!
Try using:
__try
{
}
__except(1)
{
}
Mukkie
|
|
|
|
|
Hello,
First of all let me thank you for reading my question.
QUESTION:
Hello, I have a program that has one WM_TIMER missage (SetTimer...), This message is redistributed to some of my classes via SendMessage(...).
I know that postmessage differs from sendmessage in the fact that postmessage waits for the message to return, and sendmessage don't waits.
Do the messages that I redistribute work at the same time?
The problem is that all of them call functions in a non-thread safe DLL. (that I have not linked and I don't have the code).
As always thank you for your help.
|
|
|
|
|
No, timers aren't like threads. They are just regular messages processed in the same way as the rest. Think of the sending of WM_TIMER as if an external user makes the timing by himself and then clicks on a button to generate the message. No threading problems, right?
You can apply a simple sanity check: If you don't have explicitly created any thread with AfxBeginThread , CreateThread or _beginthread (ex ), then your program is single-threaded and you just cannot suffer any threading problem.
In a single-threaded Windows app, all of your messages are driven by a unique message pump, which in fact serializes message processing. Two situations can arise:
- If you broadcast your message in your
OnTimer handler with SendMessage s, then each SendMessage executes directly (rather than thru the message pump) and completely. So, no concurrency problems here. - If you do the broadcasting with
PostMessage s, all the messages get queued and are serially executed by the message pump. No problem either.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Although Joaquin has already answered your question I just want to emphasized that you have gotten the SendMessage/PostMessage difference all backwards.
SendMessage is synchronous, meaning that the function calling SendMessage will be blocked until SendMessage returns (as if SendMessage was just another C++ function)
PostMessage is asynchronous, and basically it just puts you message on the receiving window's message queue. However, the handler of the posted message will not be called until the function calling PostMessage returns control to Windows (this is usually done in the message pump through calls to GetMessage/PeekMessage).
Cheers
Steen.
"To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
I have a question then... (sorry for that).
The program that I'm talking about is a Numerical Control, then I need to ask for the coordinates of the machine and to look for possible errors that could have happened, and so on... (also I have to be able to send information to the DLL that allow me to retrieve and to send data to the Numerical Control Interface DLL).
I want this process to be as fastest as it can, and I have written a WM_TIMER message that is sent to everywhere in wich requiring data is needed: getting coordinates, errors, status...
The WM_TIMER handler is called each 10 Ms and re-sent to all those places that need the notification.
In this situation I believe that is the same that I use the SendMessage or the PostMessage because at the end I will be asking a lot of times the same information.
Wich one do you think that's the best choice? (SEND or POST)message?
As always thank you very much for your help and attention.
|
|
|
|
|
In a single threaded app, the only difference it makes is in the order that the code is executed.
somecode
SendMessage(somewhere...
Somemore code
Some more code, as you know, does not execute until the message has been processed.
somecode
PostMessage(somewhere...
Somemore code
In this case Somemore code will execute immediately, while the message sits in a queue.
If your main program doesn't run out of things to do (e.g. go to an idle state), the message handlers will never execute.
e.g.
void doit(
{
while (true)
{
somecode
PostMessage(somewhere...
Somemore code
}
}
in this case the message will never be handled.
versus something like
void doit()
{
somecode
PostMessage(somewhere...
Somemore code
}
in this case the message may be handled (depending on what other messages are already in the queue) immeidately after the doit procedure ends.
Therefore, SendMessage lets the sender control WHEN the message is processed, while PostMessage leaves it up to the vagueries of your message handler.
Hope this helps,
Bill
Thanks for the help,
Bill
|
|
|
|
|
I'm not quite sure I fully understand your program design. What are you Send/PostMessaging to? Windows in your app, other apps on the same PC, other apps on different PCs? If the targets of the message is in another process I'd go for your current design, using PostMessage. However, if the targets are in-process I'd let each target be represented by class. On creation each of these classes registeres itself to your OnTimer-handling class (you could keep an array of CTargetClass pointers). On each WM_TIMER I would simply call a method on each class. A simple example could look like this:
class CTargetClass : public CObject_derivative
{
public:
CTargetClass (CHandlingClass* pHandler)
....
public:
void ReturnInfo (CInfo* pInfo);
}
CTargetClass::CTargetClass (CHandlingClass* pHandler)
{
pHandler->RegisterTarget(this);
}
class CHandlingClass : public CSomeBaseClass
{
....
public:
void RegisterTarget (CTargetClass* pTarget);
afx_msg void OnTimer(UINT nIDEvent);
protected:
int m_iMaxTargets;
CTargetClass* m_pTargets;
}
void CHandlingClass::CRegisterTarget (CTargerClass* pTarget)
{
m_pTargets[m_iMaxTargets] = pTarget;
m_iMaxTargets++;
}
void CHandlingClass::OnTimer (UINT nIDEvent)
{
if (nIDEvent == ID_OF_YOUR_TIMER) {
int i;
CInfo info;
for (i=0; i<m_iMaxTargets; i++) {
m_pTargets[i].ReturnInfo(&info);
DoWhateverYouNeedWithTheInfo(info);
}
}
}
Lots of stuff omitted, but I hope you get the idea.
Cheers
Steen.
"To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
Hi,
How to access network shared resource(with UNC name) from a service
program?
for example: A service program MyService will try to open a file
MyFile.dat which resides at shared folder SharedFolder on another
machine named AnotherMachine.
\\AnotherMachine\SharedFolder\MyFile.dat
If the service MyService is configured as LocalSystem, error message
"Access to \\AnotherMachine\SharedFolder\MyFile.dat was denied."
If MyService is as valid NT account, error message
"An unknown error occurred while accessing \\AnotherMachine\SharedFolder\MyFile.dat"
Thanks for your help!
Chris Wang
|
|
|
|
|
Your second case sounds very suspicious. Have you tried stepping through the code in your service to see what happens to the file open?
What file access methods do you use? Please post the code that opens the file along with the code that produces these messages.
My guess is that the first case can be taken at face value, when the service runs as the local system account, it may not have permissions on the network resource. (One solution is to just give it permission).
The second case does not look like a permissions problem at all, but rather some other bug in the code.
HOpe this helps,
Bill
|
|
|
|
|
Hi all,
With VC7(.NET), following code give me a surprise!!!
-------snippet-------
int main(void) {
char x = 0xf0;
return 0;
}
with VC7, x = 0, with VC6 sp5, x = -15(0xf0).
when i change assignment to followings:
1) char x = static_cast<char>(0xf0);
2) char x = (char)0xf0;
3) memcpy(&x, "\xf0", 1);
4) unsigned char x = (unsigned char)0xf0;
nothing changed, x = 0.
what's the problem? me, ANSI/ISO standard, or VC7?
|
|
|
|
|
(First of all, I guess there's a typo in your post and you meant -16 instead of -15.)
This is most surprising! According to the standard, the behavior you're describing is compliant: you're trying to convert a value outside (signed) char range (namely 0xf0=240), and the standard marks this as undefined behavior. 1) 2) are equivalent, about 3) I'm not sure what's the expected behavior, and as for 4) the expected value of x is 240, not 0 (Could you check 4) again?)
What strikes me is that, despite the undefined behavior, the simplest solution, in terms of resulting code, would be that x was set to -16 (no overflow checking, direct bit pattern reinterpretation). Moreover, it is highly unlikely that MS decides to change the way its compiler behaves in such a delicate subject, thus breaking backward compatibility to gain esentially nothing. Could it be that this is a debug mode feature, and in release mode x is -16 like in the old days? Could you check that?
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I think 3 would set x to the value of 'x'. You will copy one character from the string "\xf0" to the variable x. I don't think x is a standard escape character, so the \ will produce a warning and disappear at compile time leaving "xf0". The code copies 1 character so that would be the 'x'.
Thanks for the help,
Bill
|
|
|
|
|