LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-20-2006, 05:36 PM   #1
pervert
LQ Newbie
 
Registered: Apr 2006
Location: England
Distribution: Slackware 10.2
Posts: 3

Rep: Reputation: 0
socket blocking problem


select() is staying blocked after close() is called, surely this isn't normal? The program connects to my local webserver and waits for input, about 1 second after waiting, threadfunction calls close(), select never returns. Well that's what I get when the program is run from a shell, if it's run in gdb, select returns -1 and errno is 9 (bad file descriptor).

Is this normal behaviour? ...I can't see how it is. Can somebody please compile my code and report the behaviour. I'm feeling my system is screwed up

Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <unistd.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <errno.h>

void * threadfunction(void *arg)
{
	printf("threadfunction started\n");
	
	int fd=*(int *)arg;
	
	sleep(1);
	
	printf("closing socket\n");
	close(fd);
}

int main()
{
	int fd=socket(AF_INET,SOCK_STREAM,0);
	
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_addr.s_addr=inet_addr("127.0.0.1");
	addr.sin_port=htons(80);
	
	connect(fd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in));
	
	fd_set readfds;
	FD_ZERO(&readfds);
	FD_SET(fd,&readfds);
	
	pthread_t thread;
	pthread_create(&thread,NULL,threadfunction,&fd);
	
	printf("calling select()\n");
	int ret=select(fd+1,&readfds,NULL,NULL,NULL);
	
	printf("select returned %i\n",ret);
	
	printf("errno is %i\n",errno);
	
	return 0;
}
gcc test.c -o test -lpthread

If it needs to be known, i'm running:
Slackware 10.2
Linux kernel 2.4.31
libpthread-0.10.so
libc-2.3.5.so

Thanx
 
Old 05-20-2006, 11:16 PM   #2
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
The way the program is written there is no guarantee which will execute first, the statements after pthread_create() or the code in the thread function.
Its possible the debugger is just intrusive enough to change the outcome.

If the thread function closes the socket before the select call then a socket error should occur.
On the other hand if the select call is first then it should block.
 
Old 05-21-2006, 01:24 AM   #3
pervert
LQ Newbie
 
Registered: Apr 2006
Location: England
Distribution: Slackware 10.2
Posts: 3

Original Poster
Rep: Reputation: 0
Even if I used a syncronisation object, I couldn't be sure which was called first. sleep() should suffice though, the main thread should be running while threadfunction is sleeping. The weird thing is, when I stop the process (ctrl z) during sleep(1), I can see select has been called, looking at thread 1's backtrace, yet when the process runs through it's as if close was called first.

Anywayz, the issue with the debugger wasn't my original problem. My original problem was, select is not returning after close is called.

Quote:
On the other hand if the select call is first then it should block.
You're kidding me? But it doesn't make any sense to keep an i/o function blocked when the file or socket has been closed - it will never return.

btw, program still blocks when select is replaced by recv.
 
Old 05-21-2006, 11:02 AM   #4
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
I know it seems like a good idea to have select() break when one of the file descriptors its waiting on is no longer valid, but actually thats not how it works. Select simply waits for the data read or write events. When the socket is closed this is not a data read event so select() does not break.

I always use non-blocking sockets so send() does not block, and supply a timeout with select() to test for received data. Its the user's responsibility to test for errors and handle them, select() is not designed to do that for the user.
 
Old 05-21-2006, 01:28 PM   #5
pervert
LQ Newbie
 
Registered: Apr 2006
Location: England
Distribution: Slackware 10.2
Posts: 3

Original Poster
Rep: Reputation: 0
It's fixed! I'm using shutdown() instead. I read somewhere that close() only closes the connection when the descriptor's reference count is equal to 0, I suspect this is the problem?

Oh well, thanks anyway.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
fseek on a socket descriptor to discard socket buffer? Thinking Programming 1 12-06-2005 09:15 PM
cannot read data at server socket, though client socket sends it jacques83 Linux - Networking 0 11-15-2005 01:58 PM
Unable to connect to UNIX socket /tmp/.esd/socket error while using grip dr_zayus69 Linux - Software 4 08-23-2005 07:28 PM
Help on socket Programming non-blocking io mounterriver Linux - Networking 3 03-21-2005 07:43 AM
C socket non-blocking bob66 Programming 1 03-13-2005 10:21 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:57 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration