|
-
August 16th, 2001, 04:15 PM
#1
Is CSocket there?
I am working on an internet project in which I have created a client program and server program that interact. Multiple clients access the server at once. My trouble: when a client machine locks up or has some kind of error that causes my client program not to function, the server program is not notified and attempts to send information to the client as normal. This causes the server program to hit a run time error, locks up the server program, and causes all clients to be booted.
I am using a CSocket derivative class I wrote and CSocketFiles with CArchives to do my interaction. Is there a way that my server's socket can test an individual connection to make sure the far socket is still functional before I send information across? I don't really care if a client locks up; I must make sure that one client's screw up doesn't crash the whole board. Please help me.
Thank you in advance.
-
August 28th, 2001, 02:51 PM
#2
Re: Is CSocket there?
hi friend, unfortunately i'm not sure how to solve your problem. I sugest you to make an rotine who run in the client and only response some package, like protocols works, you send from the server some package and the client application check if this package arrived, if yes then the client app send back another package who say "i'm here" and then, when the server app receive this, he send the important message.
Well, the theory is kind of this, sorry if maybe i don't help you a lot.
I wanna ask you something.
How can i make a simple sockets tranference using TCP?
I mean, with the CSocket class.
I need to create a socket, after this i need to estabilish a connection and after i need to send.
Is this write?
If you can explain me how can i do this, i will apreciate.
Maybe you know the functions like
CSockets::Create()
CSockets::Connect()
CSockets::Send()
CSockets::SendTo()
whitch this functions shoud i use?
and in which order?
well thank you anyway
|>
<<===|wellcome to "Zé world"==========>
|>
-
August 28th, 2001, 03:32 PM
#3
Re: Is CSocket there?
I would be happy to help you (if I can). I will tell you what I do in establishing CSocket connections. I don't know if it is the best way but it works for me and I try to keep things simple.
First, I create a class derived from CSocket, named CMySocket perhaps.
Next, I create 5 virtual void functions in the derived class named:
OnAccept(int nErrorCode)
OnConnect(int nErrorCode)
OnSend(int nErrorCode)
OnReceive(int nErrorCode)
and
OnClose(int nErrorCode)
These functions are overridden. They will be automatically called when the socket can accept a connection, is connected, can send info, can receive info, and has been disconnected remotely (respectively).
In these functions, I provide code that merely calls a function in the main class I working with (for me it is usually a dialog class and I have each function call MyDialog.Send() or MyDialog.Receive() etc)
One program must act as a server and one as a client.
The server program must have 2 instances of your CMySocket.
The client will have 1.
One of the server sockets must be created bound to a specific port of your choosing.
ServSocket.Create(4000);
Then it should listen for connection attempts:
ServSocket.Listen();
The client socket can be created without a port specified:
ClientSocket.Create();
It should attempt to connect to the ServSocket using the IP address (as a CString) and port number (int):
ClientSocket.Connect(sAddress, iPort);
The server socket's OnAccept function will then be called. The server socket must accept the connection and assign it to the second server socket:
ServSocket.Accept(ServSocket2);
The clients socket's OnConnect function will then be called if the connection is made.
From there you will do your communication between ServSocket2 and ClientSocket. When one sends the other's OnReceive will be called. To actually send information, I use instances of CArchive's bound to CSocketFile's which are bound to the CMySocket instances. To figure these out it would probably be better to consult MSDN than me.
Hope I've been helpful. Let me know if so. If not, sorry.
-
August 28th, 2001, 05:09 PM
#4
Re: Is CSocket there?
I don't have a lot of experience with socket, but I will try to help...
one way to solve your problem is implementing the OnClose() function to know when the connection with the client was lost. The way I do it is, I use a CAsyncSocket -- this is specially usefull when you are building a server application and can't afford to be waiting for data to be sent -- and I pass all events to the main application... for instance, the CMyAsyncSocket.OnReceive( errorcode ) calls the CMyDialog.OnSocketReceive().
But then again, I don't have a lot of experience with sockets... but I learned a lot from a file transfer server/client application that I developed a couple months ago.
Hope it helps,
Roger
-
August 29th, 2001, 04:02 AM
#5
Re: Is CSocket there?
When a socket is closed under normal conditions there are a few low level messages sent between client and server to make sure both ends are released cleanly. Unfortunately, when a client locks, this procedure is not followed.
The only way to detect failures of this kind is to check the return value after attempting to send data. If the return value is zero then the connection has been closed cleanly at the far end. If it is less than zero (SOCKET_ERROR) then the connection has failed. You can use CAsyncSocket::GetLastError() to find more details of the error, but the thing you must do is to close the server end of the connection and release the resources.
What is it that you do in your server that causes the run time error? Is it that you continue trying to use the connection even though it has failed? Or is it the action of trying to send data that makes it crash?
It shouldn't be the latter case but if you want to post the offending section of code we might be able to give a more detailed answer.
Relax and Enjoy!!!
P.S. You would be amazed at how few people have the common decency to say if an answer helped (or not).
-
August 29th, 2001, 04:38 AM
#6
Re: Is CSocket there?
Your problem is a classic one. How do you get notified when a host is down ?
The TCP/IP stack basically provides for a Keep Alive Timer, you get to know if the other host is down. Try exploring....
CSocket::SetSockOpt( int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel = SOL_SOCKET );
Set the value of lpOtionValue to SO_KEEPALIVE
But there is catch...Keep alive timer won't notice disconnections before 2 hours, any interval specified below that will default to 2 hours.
So you may have to use a application level timer, the clients keep sending signalling bytes for let say every 10 seconds.
The server needs to detect any lapse from clients, whichever fails maybe considered down.
If a signal packet is received reset the timer. The timer needs to reset in case data packet arrives as well.
This approach has worked for well in all projects no matter what platform.
Good Luck !
______________________________
Subrato Roy
Senior Systems Engineer, Telecom
Siemens Information Systems Limited
Gurgaon
Phone +91 (124) 63436/18 to 22 Extension 2171/2172
[email protected]
http://www.sislindia.com
-
August 29th, 2001, 08:26 AM
#7
Re: Is CSocket there?
My programs will in most circumstances be used for less than 2 hours at a time. I had thought about having some sort of validation code sent on regular intervals, but was hoping that there was an easier/more efficient way. Perhaps I will just take your advice and go that route anyway.
Thank you very much. You have been helpful.
-
August 29th, 2001, 08:35 AM
#8
Re: Is CSocket there?
As far as I can tell, the error is generated when information is sent from the host to a client which has locked up. I need to dig a bit deeper to be sure though. If it is the action of sending that generates the error, then (if I understand correctly what you suggest) the host would generate an error before a return value (SOCKET_ERROR) could ever be received and tested. I may be wrong though. Due to time restraints today, I will not be able to test that theory.
The section of code that handles the sending (and generates errors) is rather large and fairly involved, so I think that posting it would be a useless hassle for the most part.
Any other suggestions? Thank you for the input. You have reminded me to utilize the GetLastError() method, which I havent used yet. thanks
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|