I have simple client server application using BSD sockets.
Client is connected to server using LOCALHOST using TCP sockets.
I have used SetSockOpt - SO_REUSEADDR before bind function.
In particular case i am getting SetSockOpt functions completes with No
error but still bind fucntion fails with error that port is in use.
Case is i have three users of my MAC machine. User A logged
in,Application is successfull to bind the port and client also gets
connected successfully. Now i m closing my Client server application
and switching to another user and try to run my server application.
Here my socket cannot able to bind on port and fails with an error
that it is in Use. Suprisingly if i try with after 1 or 2 minutes it
gets binded successfully.
It is here bit difficult to judge why this is happing only when
switching the user. As if I run my application number of time in same
user it will never give me such error. Either i force terminate the
process or close it smoothly.
Even more, the first user tried to bind the port will always able to
bind successfully untill rest of the user fails in binding.
In short, X user is successed in binding the port and we are switching
the user one need to wait for 1 min and then only that user can bind
the same port.
I don't think this is a MACOSX problem or Objective - C problem. I
still looking into my code and find the solution of this.
Can anyone ever seen such problem in MACOSX?
Thanks,
Archita
Can you post this area of code? There are couple of minor
variations of theme that might be significant.
> In particular case i am getting SetSockOpt functions completes with No
> error but still bind fucntion fails with error that port is in use.
That may well be the case - as I think you are aware, REUSEADDR only
bypasses some checks when binding to a port. If the port is indeed
bound by another process, the second bind will still fail.
> Case is i have three users of my MAC machine. User A logged
> in,Application is successfull to bind the port and client also gets
> connected successfully. Now i m closing my Client server application
> and switching to another user and try to run my server application.
> Here my socket cannot able to bind on port and fails with an error
> that it is in Use. Suprisingly if i try with after 1 or 2 minutes it
> gets binded successfully.
>
> It is here bit difficult to judge why this is happing only when
> switching the user. As if I run my application number of time in same
> user it will never give me such error.
Wow, that's interesting. I've never heard of multiple users causing
problems, but then again I'd say that would be a rare situation.
Generally anything that binds to a port and listens as a server
will be run by one superuser and only once. Not that that should
prevent you from doing what you want.
The 1-2 minutes thing certainly does sound like REUSEADDR should
fix it up though.
> Either i force terminate the
> process or close it smoothly.
Ah, but does the process close() the socket it bound to?
> I don't think this is a MACOSX problem or Objective - C problem. I
> still looking into my code and find the solution of this.
Post some relevant code if you want a few more eyes to help you
out.
--
*--------------------------------------------------------*
| ^Nothing is foolproof to a sufficiently talented fool^ |
| Heath Raftery, HRSoftWorks _\|/_ |
*______________________________________m_('.')_m_________*
Hi,
Thank you for your reply.
I am posting my code here.
int socketId;
int clientSocket;
both are class vairables
Two methods
- startOnPort
-stopListening
- WaitForConnection (Thread Function)
Code here
-(BOOL)StartOnPort:(uint32_t)port
{
struct sockaddr_in listeningAddress;
//Create a socket to listen for request
if((socketId=socket(AF_INET,SOCK_STREAM,0))<0)
{
//Unable to create the socket
return NO;
}
//Fill stucture
bzero(&listeningAddress,sizeof(listeningAddress));
listeningAddress.sin_family=AF_INET;
listeningAddress.sin_port=htons(port);
listeningAddress.sin_addr.s_addr=htonl(INADDR_ANY);
//Set option for reuse
int on=1;
if(setsockopt(socketId,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)
{
NSLog(@"Unable to set reuse option.");
}
//Now bind the address
if(bind(socketId,(struct sockaddr
*)&listeningAddress,sizeof(listeningAddress))<0)
{
NSLog(@"Unable to bind socket errno=%d",errno);
close(socketId);
return NO;
}
[NSThread detachNewThreadSelector:@selector(waitForConnection:)
toTarget:self withObject:nil];
isListening=YES;
return YES;
}
-(BOOL)stopListening
{
if(!isListening)
{
return NO;
}
close(socketId);
close(clientSocket);
isListening=NO;
return YES;
}
-(void)waitForConnection:(id)anObject
{
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
unsigned char buffer[BUFFER_SIZE];
struct sockaddr_in clientAddr;
unsigned int addSize=sizeof(clientAddr);
//Listen for connection
listen(socketId,2);
NSLog(@"Waiting for connection..");
if((clientSocket=accept(socketId,(struct sockaddr
*)&clientAddr,&addSize))<0)
{
NSLog(@"Error in accepting connection");
return;
}
NSLog(@"Connection accepted.");
while(!isFinished)
{
int result=read(clientSocket,buffer,BUFFER_SIZE);
if(result<=0)
{
NSLog(@"Error in reading the data. %d",errno);
break;
}
//Pass data for processing
received(receiver,@selector(receive:
length:),buffer,result);
}
close(clientSocket);
[pool release];
NSLog(@"Thread exiting.");
}
Let me know if anything written in the code, cause this issue.
Thanks a lot.
Archita
<CODE SNIPPED>
No, the code you posted definitely looks fine. I suspect now
that your -stopListening method is not getting called when
you think it is. If close() is not called on that socket, then
the OS probably wont give it up straight away.
Hi,
Thank you for reply.
I have checked my code twice. I have kept NSLog and also verify that
my function is called when I am closing my application.
Also i used to check netstat and check ports and its status.
Any other clue. Why this is happen. Interesting thing is i have
started preparing sample application. Server and client. Whenever
client connects successfully to server. I used to close both server
and client application and logged into other user. In this case also,
I am facing error on bind.
One thing I can say is initially i had created only server
application and number of times i have close and run server
application in different user. Also I had kept my server application
in user's log in. But that time I was able to bind my port
successfully everytime.
And when i have started client application and try to connect and then
switch user. I am facing the same problem.
Reply me if anything specific to be take care of in such cases.
Thanks,
Archita
I'm afraid I don't know what else to suggest. It sounds like a
curious problem, probably specific to the multi-user environment
of OS X. Unix is fundamentally a multi-user OS so there really
shouldn't be any problem with different users trying to access
the one server. Therefore, I'm sure if you were able to find
anything else out people would be happy to hear about it.
Perhaps you could try keeping telnet or netcat handy, and when
you get a "port in use" error, telnet/nc to the port to see if
anything responds. Or you could try using multiple users at the
command line (use the su command to switch users) instead of OS X's
interface for switching users. That might help you narrow down
where in the process the problem is occurring.
One last thing is that it is good practice to trim the signature
from the post you are replying too. Most news readers will
automatically do so if the signature is proceeded with a
dash-dash-space, as mine is below.
Good luck!