I have a button in server program which when clicked displays the received data:
m_Mesg=(CString)buff;
UpdateData(FALSE);
but its displaying garbage value.
Can somebody help me with that?
Zulfi.
Andreas Masur
February 27th, 2004, 09:38 AM
[Moved thread]
Andreas Masur
February 27th, 2004, 09:39 AM
Well...pointing out the obvious...what do 'send()' and 'recv()' return?
Mathew Joy
February 28th, 2004, 12:02 AM
Yes, as Andreas said, I'd like to stress the point that every winsock API call should be checked for error condition. In your case you should check for SOCKET_ERROR and use GetLastError() to retrive the error no. My guess is that the culprit is closesocket() call immediately after the send(). To ensure all the data is send/recvd properly, you should call shutdown() before calling closesocket()
return TRUE; // return TRUE unless you set the focus to a control
}
//Client applic.
//This is another program
void CClientPrgDlg::OnSend()
{
// TODO: Add your control notification handler code here
WORD sockVersion;
WSADATA wsaData;
int nret;
connect is returning -1. That means it is an error condition and the error no has to be retrieved using GetLastError(). What does it return? One problem (after a quick glance) in your code is, you are not checking the status of send()/recv() after the call, which should be done as mentioned in my previous post.
Zulfi Khan2
March 9th, 2004, 04:59 AM
Thanks for your response. I feel its not able to find the server. There can be some prob with addressing. I will check the error code but I dont understand checking for the return value of send & recv ( ) at this point. If connect wont work then send & recv will not work too.
Zulfi.
Mathew Joy
March 9th, 2004, 05:12 AM
Well, for the time being it is OK. Speeking from the other side, send/recv may fail even if the connect works. So to make your code robust and trouble free, you have to check it.
sprintf(szBuf, "failed: GetLastError returned %u\n",
dw);
m_ErrMsg=(CString)szBuf;
I got following error code mesg:
failed: GetLastError returned 10060
What does it mean & how can I solve it?
Zulfi.
simpleman
March 9th, 2004, 08:40 PM
Hi Zulfi Khan2
i am simpleman
i read your server side code. then there is no "listen()" after binding the 'listeningSocket'
will you add listen() function and try it again ?
Mick
March 9th, 2004, 08:47 PM
You should be using WSAGetLastError(...) rather than GetLastError(...) for winsock error codes. You can find the error codes on msdn.microsoft.com. The error code you posted should be "connection timed out". You can also use errlook.exe (part of the VC++ install) to get error codes/format messages...
Mathew Joy
March 9th, 2004, 10:54 PM
Originally posted by Mick
You should be using WSAGetLastError(...) rather than GetLastError(...) for winsock error codes... Its all the same, Mick. WSAGetLastError() is mapped to GetLastError().
Zulfi Khan2
March 10th, 2004, 06:23 AM
I am getting bind error now:
failed: GetLastError returned 10048
Zulfi.
Mick
March 10th, 2004, 06:35 AM
Originally posted by Mathew Joy
Its all the same, Mick. WSAGetLastError() is mapped to GetLastError().
it may wind up in _RtlGetLastWin32Error but it is a different path...
Mick
March 10th, 2004, 06:42 AM
Originally posted by Mathew Joy
As far as I know, it is a direct mapping. The only difference is the naming convention.
I won't argue the point mat...it's just a jmp (for now) and the for now is the point I am making...
Mathew Joy
March 10th, 2004, 06:43 AM
Originally posted by Mick
it may wind up in _RtlGetLastWin32Error but it is a different path... As far as I know, it is a direct mapping. The only difference is the naming convention.
Mick
March 10th, 2004, 06:44 AM
Originally posted by Mathew Joy
As far as I know, it is a direct mapping. The only difference is the naming convention.
now that is wierd...I think I got foobared when Brad bumped me up...see my post that is like a minute early...guess I need to log out and log back in...wierd....
Mathew Joy
March 10th, 2004, 06:59 AM
Originally posted by Zulfi Khan2
I am getting bind error now:
failed: GetLastError returned 10048
Zulfi. 10048 - WSAEADDRINUSE: the address(local ip addr and port no) is already in use by some other socket.
//Just a little bit of research will do Mick;). As always google.groups :)
Mick
March 10th, 2004, 07:05 AM
Originally posted by Mathew Joy
10048 - WSAEADDRINUSE: the address(local ip addr and port no) is already in use by some other socket.
//Just a little bit of research will do Mick;). As always google.groups :)
Not sure what you mean mat?
set the SO_REUSEADDR using setsockopt(...)
Mathew Joy
March 11th, 2004, 12:41 AM
Originally posted by Mick
Not sure what you mean mat?
Not sure by what you mean either Mick.
set the SO_REUSEADDR using setsockopt(...) Sure, you can bind to a already using address, but to which socket will receive the notifications of incomming connections is undefined behavior.
shivakumarthota
March 11th, 2004, 04:32 AM
I have noticed that you have not set the size of the buffer in the program when you are sending and receiving. Determine what is the maximum size of the data that you want to send or receive. Try to set the size of the buffer to this maximum size.
The second point is that the port to which you might be trying to connect might already be in use (indicated by the error number 10048). Change the port number. Try a port number which is above 6000.
This should solve your problem.
Mick
March 11th, 2004, 04:41 AM
Originally posted by Mathew Joy
Not sure by what you mean either Mick.Sure, you can bind to a already using address, but to which socket will receive the notifications of incomming connections is undefined behavior.
the last one to bind wins. Never had a listen server go down and have the socket still be in TIME_WAIT? Or did they fix that from NT?
I should note you should only use the SOREUSE on a listen server, and since we can assume the error is coming from teh bind for the listen server in what they are posting, because if you exhaust the temp ports that will be used (1024->5000) by default under NT you'll get a connection refused (unless some service pack fixed this late ninties when I found this out the hard way), under XP you'll get a 'out of bufferrs' unless you change the MaxUserPorts registry setting and bump the number over 5000 (this for calling connect on an unbound port) but it's doubtful you are generating enough connects give your code you posted to exhuast that socket limitation.
Mathew Joy
March 11th, 2004, 04:56 AM
Originally posted by Mick
the last one to bind wins. Nothing to confirm this Mick. Both in documentation and tests reports it is said to be undefined. Meaning any can recv. Never had a listen server go down and have the socket still be in TIME_WAIT? Or did they fix that from NT? Well a closed connection will be in a TIME_WAIT for 2 * MSL, that is almost 4 mins. So if the listening socket uses the SO_REUSEADDR it can reuse the address before some other socket binds to it.
Mick
March 11th, 2004, 05:04 AM
Originally posted by Mathew Joy
Nothing to confirm this Mick. Both in documentation and tests reports it is said to be undefined. Meaning any can recv.
Actually it is documented cause I read it somewhere ;), I'll look for the link if you like. I am talking only a bind for a listen server just to be clear.
Well a closed connection will be in a TIME_WAIT for 2 * MSL, that is almost 4 mins. So if the listening socket uses the SO_REUSEADDR it can reuse the address before some other socket binds to it.
that was my point.
Mathew Joy
March 11th, 2004, 05:19 AM
Originally posted by Mick
Actually it is documented cause I read it somewhere ;), I'll look for the link if you like. I am talking only a bind for a listen server just to be clear. Well, I was talking about more than one bind on a single address (ip,port) and the bound sockets on active listen. If you have a documented link that says the behavior is defined, I'd love to look at it.:)
Mick
March 11th, 2004, 05:45 AM
Originally posted by Mathew Joy
Well, I was talking about more than one bind on a single address (ip,port) and the bound sockets on active listen. If you have a documented link that says the behavior is defined, I'd love to look at it.:)
I think we are talking two seperate things, as I see it the OP didn't have an active listen, and I am assuming the listen socket was in TIME_WAIT. Having two active listens I would think would be the first one to bind. Maybe I used a poor chocie of words in teh last one to bind comment, I am talkinga bout a listen server, who's socket is in a TIME_WAIT and the need to use soreuseaddr otherwise your going to be sitting around waiting for that socket to be released 2 * the MSL....
edit: maybe that is no longer an issue these days? It was back under windows NT sp 2 or sp3....
Zulfi Khan2
March 15th, 2004, 06:27 AM
I was also surprised to find how we can bind to an already use socket. It may be a solution to my prob but I dont like to do this. Actually what's happening is that my prog is loaded but the dlg box is not displayed. So I have to rerun it feeling that it didnt run. And that's the time I get bind error (bind to an inuse socket). I found that when I first time executed the program, it executed but without displaying the dlg box. Later on I checked the Task manager & I found that program is running. Then I debug my program line by line & found that this behaviour is attributed to accept ( ). If I put the code from accept to the end of program in comments, the opening dlg box is displayed . Otherwise if I run it along with accept, it doesnt show me the dlg box. Thus driving me to run it again & henceforth generating the bind error.
Can somebody help me with that?
Why is this so much troublesome compared to Java?
Zulfi.
Mathew Joy
March 15th, 2004, 06:47 AM
Now, let me try to put things straight. SO_REUSEADDR is not the solution in your case. AFAIK the real use of SO_REUSEADDR is to either create a malicous program to bind to an existing address or to restart a server by using the same port. Other than that I don't know if there is other uses.
Your problem is that on the first run, your socket is bound to the address. Then on the second run, you get the error because the first exe is running and the second program is trying to bind to the address used by the first. The bug is with the app program. Not quite with your usage of winsock.
Mathew Joy
March 15th, 2004, 06:58 AM
Just an advice: Do not use any blocking calls in UI threads. You should create seperate threads for it. Otherwise displaying UI will also be blocked!!!
Zulfi Khan2
March 15th, 2004, 07:46 AM
Mathew Joy,
I would try your advice & let u know.
Zulfi.
Zulfi Khan2
March 18th, 2004, 06:01 AM
Hi,
I created the thread. There is no blocking this time but the ultimate result is a still failure with an error code of 10060.
The changed srver code is given below:
I dont know to check whether the thread is running or not.
What else i have to check?
Still waiting for sol on this.
Zulfi.
Mathew Joy
March 18th, 2004, 06:55 AM
Well, I can't make much from your code. Next time onwards use 'code' button on the post reply page, to paste the codes, also reasonably indented.
Few mistakes that I've noticed:
Why are you using WSACleanup() everywhere. There should be only one cleanup per startup. Do the cleanup in the destructor.
Your thread only executes once. You should have a big loop.
Close the listening socket only when you are done with the program/server.
How many clients do you intend to connect?
The biggest problem is, you are not handling the error. You call WSAGetlastError() fine. Don't you want to see this error code? Without seeing the error code how can you tell if the calls are completed successfully? I rekon telling these things in the begining of the thread.
I guess what is happening is that you call WSACleanup as soon as the thread is created and accept() fails with an error (prob WSANOTINITIALISED 10093) that you do not handle. So there is no service for the client to connect.
I think a design that would suit your need is: a loop that just do accept. For each accept() create another thread that handles the client. Once the peer is closed, you can exit from the thread. I suggest you read some material about writing a simple tcp server. You have lots of sample codes on the net. Spend some time with it before writing your own. I can only outline the design. It is not possible to teach in a few posts like this.
Zulfi Khan2
March 18th, 2004, 08:09 AM
Hi,
Thanks for getting back with me on this.
I have removed the WSACleanup() after the the thread creation code. Other places at which I am using the WSAClanup ( ) are when there is a socket error & I want to end up. Dont u think that it makes sense?
I have put a big loop now in the code of the newly created thread:
UINT ThreadFunc(LPVOID param) {
SOCKET theClient;
int nret;
char buff[30];
int m_ret;
for (;;) {
theClient = accept(listeningSocket, NULL, NULL);
At this point I am just interested in a single client.
Just the client sends a single mesg & server receives it.
I have got the error wrt to connect & that's 10060.
The design u have told me is quite fine. I have seen it for non-UI based application involving UNIX. But my case is different. I am already creating a thread to handle the UI prob. Also at this point I am interested in a iterative server.
Hope u can understand my prob.
Zulfi.
Mathew Joy
March 19th, 2004, 12:30 AM
Oh boy, where do you handle the error? You have to see it somehow. Display it, log it or do something. Using wsacleanup() after every error is a bad idea. An error means that the call wasn't successfull, not the whole winsock. So as I said close at the end of the program.
Now, WSAETIMEDOUT 10060 at connect generaly means that there is no service running at where you are looking to connect. So in your case, either you are not connecting to the proper address (ip, port combination) at the client side, or your socket is not listening. Now study, think and find the error.
Good Luck :thumb:
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.