|
Paolo Messina wrote:
For the whole thread
Yes. More than the solution, it was your approach which I thought was amazing! Slowly moving towards the goal.
Joaquin had posted this link in one of his posts today [Mar 7th 2002]. That's why I actually replied to a thread that's almost half an year old
Nish
[Signature temporarily down]
|
|
|
|
|
hi, ok first of all, this project is pure win32, no MFC involved. I'm making a server that can accept multiple clients, when a client sends some data, the server sends it back to all connections. I'm using the sockets in asynchronous mode, i've already made the client but i'm having problems with the server and i've been trying to firgure it out for so long, i thought i'd try here. I can't find any example on the net of this, and i'm starting to believe there isn't one, all i could find was a server that used threads and echoed the data back to the connection the data was sent from.
This is what i have so far:
First i create a socket that listens for incoming connections, this socket is called "sd". then i have an array of 50 sockets: ac[50]
i initialize all these sockets with a loop from one to 50 giving them the value "NULL"
This is the code that is executed when the listening socket posts the FD_ACCEPT message to accept any incoming connection:
case FD_ACCEPT:
sockaddr_in sinRemote;
nAddrSize = sizeof(sinRemote);
ac[conn] = accept(sd, (sockaddr*)&sinRemote, &nAddrSize);
MessageBox (NULL, "Accepted incoming connection." , "Accepted", 0 + MB_ICONASTERISK);
conn = conn + 1;
break;
This works fine and multiple connections are accepted. The conn integer keeps up with the number of connections established.
Now here's the problem: every incoming connection is accepted by the ac socket, the first one by ac[0], the second one by ac[1] and so on and so on... till 50.
I used WSAAsyncselect on all ac sockets from 0 to 50 so when they are ready to receive data they post a message. Now what is supposed to happen is that somehow the received data is sent back to all connections, here's what i have now:
case FD_READ:
c = 0;
do
{
bytes_read = recv(ac[c], buf, sizeof(buf),0);
buf[bytes_read] = NULL;
c = c + 1;
}
while(bytes_read<=0);
for (y=0;y<=50;y++)
{
if (ac[y]!=NULL)
{
Len = strlen(buf);
if (send(ac[y], buf, Len, 0) == SOCKET_ERROR)
{
MessageBox (NULL, "error echoing data" , "Error", 0 + MB_ICONHAND);
}
}
}
break;
I tried to make multiple telnet connections and it worked but when i sent something, it got echo'd for the first connection but then it gave me the "error echoing data" messagebox...
Can anyone please tell me how to handle FD_READ so the server sends the data back to all connected clients???
Thanks...
Kuniva
P.S.: this thing is really startin ta bug me
|
|
|
|
|
Maybe more things are wrong in your code, but take a look at that:
case FD_READ:
c = 0;
do
{
bytes_read = recv(ac[c], buf, sizeof(buf),0);
buf[bytes_read] = NULL;
c = c + 1;
}
while(bytes_read<=0);
Since the sockets are asynchronous, there is a good chance that recv(..) will return SOCKET_ERROR for most of the sockets (the ones in which there is no pending data). SOCKET_ERROR equals to -1. Which means that your
buf[bytes_read] = NULL;
statement will overwrite some memory... In debug build there are good chances you won't even notice it - but there is a good chance that in Release build the program will crash.
That would probably also damage the results of your
Len = strlen(buf)
line.
Anyway, whenever you get a SOCKET_ERROR result, check the value returned from WSAGetLastError(). If this value equals WSAEWOULDBLOCK then it means the operation will complete later. I recommend reading Windows Sockets Network Programming by Bob Quinn (I think he's the Charles Petzold of Winsock) and Dave Shute, ISBN 0-201-63372-8.
Another note - writing a server that relies on Windows messages (or event Events) is ok for a small-scale server. But in a large one that should handle thousands, and probably even hundreds of simultaneous connections, you'd probably use some other method (like IOCP).
Good luck!
|
|
|
|
|
Hi, I've to invoke an application whose path is not known. I am required to search for it in the application path instead of opening the CFileDialog can you help me how to do it
|
|
|
|
|
Hi,
I'm not sure to understand what you're trying to do, but you may look at these API:
- SearchPath()
- SearchTreeForFile()
Cheers,
Paolo
------
"airplane is cool, but space shuttle is even better" (J. Kaczorowski)
|
|
|
|
|
Thanks for your suggestion. as for the Usage I am using it to Invoke other applications Like Word Excel or Some external Reporting tool That can be used for some functionality as a part of my application
|
|
|
|
|
Thanks for your suggestion. as for the Usage I am using it to Invoke other applications Like Word Excel or Some external Reporting tool That can be used for some functionality as a part of my application
|
|
|
|
|
I want to use "Post" to send some paras to a ASP page.When I use Unicode compile mode,the asp can't receive the paras.When I use MBCS compile mode,the asp can received.
Who can give me some advice?
The code is here:
BOOL PostRequest(CString sUrl, CString sContent, CString &sResult)
{
CString strHeaders =
_T("Content-Type: application/x-www-form-urlencoded");
// URL-encoded form variables -
// name = "John Doe", userid = "hithere", other = "P&Q"
//CString accept=
// _T("Accept: */*");
//LPTSTR a=accept.GetBuffer(accept.GetLength());
CString strServerName;
CString strObject;
INTERNET_PORT nPort;
DWORD dwServiceType;
CInternetSession session;
AfxParseURL(sUrl, dwServiceType, strServerName, strObject, nPort);
CHttpConnection * pServer = session.GetHttpConnection(strServerName, nPort);
//CHttpFile *pFile = pServer->OpenRequest(0,
// strObject,NULL,1,(LPCTSTR*)&accept,NULL,INTERNET_FLAG_EXISTING_CONNECT);
if (pServer==NULL)
return false;
CHttpFile *pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,
strObject);
if(pFile==NULL)
return false;
try
{
BOOL result = pFile->SendRequest(strHeaders,
(LPVOID)(LPCTSTR)sContent, sContent.GetLength());
}
catch (CInternetException e)
{
//MessageBox(NULL,_T("Internet Exception"),_T("Error"),MB_OK);
return false;
}
catch(...)
{
return false;
}
DWORD dwRet;
pFile->QueryInfoStatusCode(dwRet);
}
|
|
|
|
|
|
hai i am a new user of MFC
As soon as i am creating a new dialog initdialog is giving assertion error. than it's dumping core.
Some Dll's are also overlapping ??
Could Any body immediately help me.
Suleman;)
suleman
|
|
|
|
|
Which line is giving the assertion? What does the call stack show?
Michael
|
|
|
|
|
HI
Is there any way to use or accommodate ‘CdialogBar’ with ‘Cdilalog ‘ ?How?
I tried to do this but an error at runtime occurred ,my code like below :
BOOL CmyDlg::OnInitDialog()
{
. .
. . .
m_DialogBar.Create(this, IDD_DLGBAR, WS_VISIBLE|WS_CHILD|CBRS_LEFT, 1);
m_DialogBar.EnableDocking(CBRS_ALIGN_LEFT);
}
Thank you ,,,
AHMAD ALWASHALI
|
|
|
|
|
I'm currently writing a file viewer and I would like to automatically unzip .ZIP files to preview their content. My unzipper is a .dll which uses the zlib library. This is a very important part of the application.
Below is the method which reads a .ZIP file in the .dll. I would like to callback my application and give it a pointer to the buffer (an array) containing each unziped file.
As I've never written any callback I don't really know how to implement this, can someone explain me the howto. Thanks in advance.
void C3DZipLoader::Load(char* fileName) {
char* pszFileName;
unzFile hUzf = unzOpen(fileName.ToPStr());
if (hUzf==NULL) return NULL;
pszFileName = new char[MAX_PATH];
if (unzGoToFirstFile(hUzf)==UNZ_OK) {
while (true) {
ZeroMemory(pszFileName, MAX_PATH);
unzGetCurrentFileInfo(hUzf,
NULL,
pszFileName, MAX_PATH,
NULL, 0,
NULL, 0);
if (unzOpenCurrentFile(hUzf)==UNZ_OK) {
// We read the stream form Zlib and get a buffer
// containing the file then we...
<do_the_callback_call_here>
unzCloseCurrentFile(hUzf);
}
if (unzGoToNextFile(hUzf)!=UNZ_OK) break;
}
}
delete [] pszFileName;
return <something>;
}
Yarp
|
|
|
|
|
how can i convert a .bmp file to .jpg file programmatically?
|
|
|
|
|
a/ use GDI+ ( see my articles )
b/ use another library like paintlib ( see the FAQ )
c/ download the jpeg library ( see any of the libraries mentioned in the FAQ, they all use/link to it )
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
How to make a group of statements act as one instruction? All of them are executed without being interrupted by other thread or none is executed.
Here is the trouble I meet:
Several threads are used in my project and I want to suspend certain threads in some conditions. I use following statements:
::GetExitCodeThread( pThread->hThread, &dwExitCode );
if( dwExitCode == STILL_ACTIVE ){
pThread->SuspendThread();
}
// pThread is the point to the thread
I have to make these statements act as one statement so that the thread will not quit and pThread is valid when "pThread->SuspendThread()" is executed.
Thanks in advance!
|
|
|
|
|
All of them are executed without being interrupted by other thread
Nope, the OS can interrupt any thread at any time. That's the whole point behind preemptive multitasking.
--Mike--
http://home.inreach.com/mdunn/
Trillian: What are you supposed to do with a manically depressed robot?
Marvin: You think you've got problems. What are you supposed to do if you are a manically depressed robot?
|
|
|
|
|
One solution might be to introduce an Event synchronization object into your program. You can associate one event object with every thread, and make it set by default. The last line in the thread's function (before it exits and the thread ends) would be "WaitForSingleObject(hThreadEvent, INFINITE)". Since the event is SET by default, most times the thread will just continue - and terminate.
Now, wherever you have a bunch of lines such as
::GetExitCodeThread(...)
...
Just reset the event object that is associated with the thread in question. Something like:
ResetEvent(pThread->hEvent);
::GetExitCodeThread(pThread->hThread, &dwExitCode);
if (dwExitCode == STILL_ACTIVE) {
pThread->SuspendThread();
}
SetEvent(pThread->hEvent);
Now, after writing that, I wonder what would happen if the thread function will PASS the WaitForSingleObject, and then a context switch will take place, and only then your ResetEvent(pThread->hEvent) will execute. In such a case, I guess your problem still exists.
So let's change that solution a little. What if, instead of depending on the thread's exit code returned by the OS, you'll manage that yourself? Again, an event object will be associated with each thread. When the thread starts executing, it will RESET the event.As long as the event is RESET - the application can know that the thread is still executing. I added a critical section there - because otherwise under certain circumstances a cotnext switch would have still caused problems.
Thread:
-------
ResetEvent(hEvent)
... thread stuff ...
...
... Want to exit ...
EnterCriticalSection(&csThread)
SetEvent(hEvent)
LeaveCriticalSection(&csThread)
App:
----
EnterCriticalSection(&csThread)
if (TIMEOUT == WaitForSingleObject(hEvent, 0))
{
// Thread is still executing
pThread->SuspendThread()
}
LeaveCriticalSection(&csThread)
And now that I think about it - adding a critical section to the previous idea should also fix it, so you can choose any of the two.
Good luck...
|
|
|
|
|
Oz,
Thank you very much!!!
|
|
|
|
|
I want to get a point to toolbar of the application. What I do is:
CMainFrame *pMainFrame = ( CMainFrame * )AfxGetMainWnd();
CToolBar *pToolBar = ( CToolBar * )( pMainFrame->GetControlBar( IDR_MAINFRAME ) );
Unfortunately, pToolBar is NULL! What's wrong?
|
|
|
|
|
I want to show [+] even the item hasn't child,
and then,when I expanded the item,if it hasn't child,the [+] hided,what should I do?
code sample will be more helpful,thank you.
|
|
|
|
|
Set the TVITEM::cChildren member to I_CHILDRENCALLBACK. This makes the control send a TVN_GETDISPINFO message to determine when to show the + button. See the docs on TVITEM for more details.
--Mike--
http://home.inreach.com/mdunn/
Trillian: What are you supposed to do with a manically depressed robot?
Marvin: You think you've got problems. What are you supposed to do if you are a manically depressed robot?
|
|
|
|
|
When you add the item you set cChildren to 1, then you have to handle TVN_ITEMEXPANDING notification and populate the item with child items. If you add no items, then you set cChildren to 0.
Paolo
------
"airplane is cool, but space shuttle is even better" (J. Kaczorowski)
|
|
|
|
|
Hi:
Can I send an e-mail using OnFileMail() function that MFC provide, but customize the content of mail, that is, use own text as mail content rather than use CDocument content as mail attachment?
|
|
|
|
|
See PJ Naughter's excellent CMapi class: http://www.codeproject.com/internet/cmapi.asp
It's very easy to use, and provides a good reference to using simple MAPI should you want to write your own code.
Or if you'd rather, just copy the code from MFC's OnFileSendMail() and replace the bit that serializes the current document with something to generate your own attachment. (this code is not as nice though)
|
|
|
|
|