Click here to Skip to main content
15,916,091 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
GeneralRe: AfxIsValidString does not seem to work. Pin
Tim Smith15-Aug-05 13:40
Tim Smith15-Aug-05 13:40 
GeneralRe: AfxIsValidString does not seem to work. Pin
mcgahanfl16-Aug-05 3:02
mcgahanfl16-Aug-05 3:02 
GeneralMake control part of Window Pin
tommazzo15-Aug-05 5:19
tommazzo15-Aug-05 5:19 
GeneralRe: Make control part of Window Pin
Prakash Nadar15-Aug-05 6:54
Prakash Nadar15-Aug-05 6:54 
GeneralRe: Make control part of Window Pin
tommazzo15-Aug-05 7:40
tommazzo15-Aug-05 7:40 
GeneralMultithreading Pin
Ali Tavakol15-Aug-05 5:04
Ali Tavakol15-Aug-05 5:04 
GeneralRe: Multithreading Pin
Bob Stanneveld15-Aug-05 5:57
Bob Stanneveld15-Aug-05 5:57 
GeneralCSocket locks up Pin
Roger Garrett15-Aug-05 4:04
Roger Garrett15-Aug-05 4:04 
A CONNECT PROBLEM WITH CSocket


I have what I think is some very simple CSocket code for a client and a server,
but I'm having difficulty getting it working since it occasionally locks up.
Any advice would be greatly appreciated.

Here's the situation:

I have a client program and a server program. I start them both up, assuring
that the server starts up first and is waiting and ready for the client. They
are both running on the SAME MACHINE.

ON THE CLIENT SIDE

When the client program is started it successfully makes a connection to the server,
sends a simple (command) string to the server, and then retrieves (data) strings
from the Server until it retrieves a special (ENDOFDATA) string from the Server that
indicates that all data has been sent. The Client then sends a final (ENDOFTRANSACTION)
string to the Server, notifying the Server that the whole transaction
is completed and so that the server knows that it can safely close the connection.

ON THE SERVER SIDE

The Server is set up and does its Accept, waiting for a connection from the Client.
When it suceeds in the Accept it then does a ReadString of the first (Command) string from
the Client. The Server then sends the several (data) strings to the Client, followed by
the sending of an (ENDOFDATA) string to the Client. The Server then does another ReadString,
waiting for the (ENDOFTRANSCATION) string from the Client. When the Server receives that
(ENDOFTRANSCATION) string the Server then closes its side of the connection.


And I do this over and over again, testing the connections and the ability
to successfully transfer data betwen the Client and Server. Generally it
works, but not always.

FAILING

When it fails, it does so as follows:

1) The Client enters the Connect method.
2) The Server does indeed Accept the connection from the Client.
3) The Server successfully sets up the sending and receiving Archives.
4) The Server then does the ReadString, waiting to read the initial (Command) string from the Client.
5) But the Server never gets the (Command) string. It waits forever inside the ReadString.

Debugging reveals that the Client is STUCK WITHIN THE Connect METHOD.
Although he Client has performed enough of the Connect method in order to actually establish the
connection (made clear by the fact that the Server Accepts the connection, successfully
establishes the related Archives and starts up the ReadString method) the Client
never does actually complete the processing of the Connect method.

So, the Server is left hanging, waiting for the (Command) string from the Client,
which will never come because the Client never finishes processing the Connect method.

And there it waits, never completing the operations.

Oddly, it works most of the time. If I include TRACE statements in the code it seems to work
more often than if there are no TRACE statements. Also, if I only send a tiny bit of data
(one or two strings) from the Server to the Client then it works more often than if I transfer
lots of strings. But it always inevitably, randomly fails.

Debugging reveals that the place where it's "stuck" is inside the CSocket::ConnectHelper
method,as follows;


BOOL CSocket::ConnectHelper(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
if (m_pbBlocking != NULL)
{
WSASetLastError(WSAEINPROGRESS);
return FALSE;
}

m_nConnectError = -1;

if (!CAsyncSocket::ConnectHelper(lpSockAddr, nSockAddrLen))
{
if (GetLastError() == WSAEWOULDBLOCK)
{
while (PumpMessages(FD_CONNECT)) << GETS STUCK IN THIS LOOP
{
if (m_nConnectError != -1) << ALWAYS RETURNING m_nConnectError = -1
{
WSASetLastError(m_nConnectError);
return (m_nConnectError == 0);
}
}
}
return FALSE;
}
return TRUE;
}




- - - - - - MY CODE follows


The code below shows the basic, stripped-down versions of the client and server programs.

What am I doing wrong?





// CLIENT CODE

AfxSocketInit();

int nNumberOfTransactions;
for (nNumberOfTransactions = 0 ; nNumberOfTransactions < 1000; ++nNumberOfTransactions)
{
CSocket ClientSocket;
int nPortNumberClient = 0; // 0 means for MFC to select an available port
if (ClientSocket.Create(nPortNumberClient))
{
int nPortNumberServer = 49153;
// Connect to the Server
if (ClientSocket.Connect("68.171.26.117", nPortNumberServer)) // <<< GETS TO HERE AND STOPS
{
CSocketFile SocketFile(&ClientSocket);
CArchive ArchiveSending(&SocketFile, CArchive::store);
CArchive ArchiveReceiving(&SocketFile, CArchive::load);

// Send "GiveMeData" (Command) string to the Server
ArchiveSending.WriteString("GiveMeData\n");
ArchiveSending.Flush(); // to assure sending of the data.

// Get response from Server
while (TRUE)
{
CString strResponse;
ArchiveReceiving.ReadString(strResponse);
if (strResponse.CompareNoCase("ENDOFDATA\n")==0)
{
break;
}
else
{
// It's actual data, do something withit
}
}
ArchiveSending("ENDOFTRANSACTION);
ArchiveSending.Flush();

ArchiveReceiving.Close();
ArchiveSending.Close();
SocketFile.Close();
}
else
{
// Connection failure.
}
}
else
{
// Failed to Create the CSocket.
}
}


///////////////////////////////////////

and here's the server code

///////////////////////////////////////

// SERVER CODE

AfxSocketInit();
CSocket SocketServer;
int nPortNumberServer = 49153;

if (SocketServer.Create(nPortNumberServer, SOCK_STREAM, "68.171.26.117"))
{
if (SocketServer.Listen(5))
{
while (TRUE)
{
// Accept the connection.
CSocket sockRecv;
if (SocketServer.Accept(sockRecv))
{
// Create a file object
CSocketFile file(&sockRecv);
// Create a receiving stream.
CArchive ArchiveReceiving(&file, CArchive::load);
// Create a sending stream.
CArchive ArchiveSending(&file, CArchive::store);

// Get (Command) string that was sent from Client
CString strCommand;
ArchiveReceiving.ReadString(strCommand); // GETS TO HERE AND STOPS

// In response to (Command) string from Server, send Data back to Client
int nCounter;
for (nCounter = 0 ; nCounter < 1000 ; ++nCounter)
{
ArchiveSending.WriteString("Data\n");
}
ArchiveSending.Flush();

// Tell Client that all data has been sent
ArchiveSending.WriteString("ENDOFODATA\n");

// Wait for acknowledgement ("ENDOFTRANSACTION") from Client
// so that I know it's safe to Close
CString strEndOfTransaction;
ArchiveReceiving.ReadString(strEndOfTransaction);

ArchiveReceiving.Close();
ArchiveSending.Close();
}
else
{
// Failed to accept the connection
}
}
}
else
{
// Failed to listen
}
}
else
{
// Failed to create the main socket
}




Roger Garrett
GeneralVC++ .NET code no longer works, originally compiled on VS2002 Pin
NuclearNed15-Aug-05 3:49
sussNuclearNed15-Aug-05 3:49 
GeneralGlobal objects in MFC Pin
TOlivier15-Aug-05 3:17
TOlivier15-Aug-05 3:17 
GeneralRe: Global objects in MFC Pin
M.Mehrdad.M15-Aug-05 3:46
M.Mehrdad.M15-Aug-05 3:46 
GeneralRe: Global objects in MFC Pin
TOlivier15-Aug-05 4:15
TOlivier15-Aug-05 4:15 
GeneralRe: Global objects in MFC Pin
Achim Klein15-Aug-05 15:01
Achim Klein15-Aug-05 15:01 
GeneralRe: Global objects in MFC Pin
TOlivier16-Aug-05 4:24
TOlivier16-Aug-05 4:24 
GeneralRe: Global objects in MFC Pin
Stephan Pilz15-Aug-05 3:51
Stephan Pilz15-Aug-05 3:51 
GeneralRe: Global objects in MFC Pin
TOlivier15-Aug-05 4:17
TOlivier15-Aug-05 4:17 
GeneralRe: Global objects in MFC Pin
Achim Klein15-Aug-05 4:45
Achim Klein15-Aug-05 4:45 
GeneralRe: Global objects in MFC Pin
TOlivier15-Aug-05 11:15
TOlivier15-Aug-05 11:15 
GeneralRe: Global objects in MFC Pin
Achim Klein15-Aug-05 12:07
Achim Klein15-Aug-05 12:07 
GeneralRe: Global objects in MFC Pin
Bob Stanneveld15-Aug-05 6:05
Bob Stanneveld15-Aug-05 6:05 
GeneralRe: Global objects in MFC Pin
TOlivier15-Aug-05 11:26
TOlivier15-Aug-05 11:26 
GeneralRe: Global objects in MFC Pin
Achim Klein15-Aug-05 13:52
Achim Klein15-Aug-05 13:52 
GeneralRe: Global objects in MFC Pin
Achim Klein15-Aug-05 13:56
Achim Klein15-Aug-05 13:56 
GeneralRe: Global objects in MFC Pin
Achim Klein15-Aug-05 14:36
Achim Klein15-Aug-05 14:36 
GeneralRe: Global objects in MFC Pin
TOlivier16-Aug-05 4:31
TOlivier16-Aug-05 4:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.