Linux: nicht verbundener socket + select



  • hallo,

    weiss jemand, warum ein nicht verbundener socket (noch kein connect aufgerufen)
    zum lesen bereit ist (und dann natuerlich ein recv -1 liefert)?

    unter windows blockiert select auch, wenn der socket nicht verbunden ist.
    und wenn ich das bissher richtig gesehen habe (bzw verstanden :)) gehen die
    stevens (progr. von unix netzwerken) beispiele ebenfalls davon aus,
    das ein select auf einen nicht verbundenen socket blockiert.

    ist das eine besonderheit von linux? muss ich noch etwas einstellen um
    select blockieren zu lassen?

    hier das testprogramm:

    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <sys/ioctl.h>
    #include <errno.h>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    
    void quit(const char* msg)
    {
    	cerr << msg << endl;
    	exit(1);	
    }
    
    int main(int argc,const char* argv[])
    {
    	sockaddr_in ia;
    
    	fill_n(reinterpret_cast<char*>(&ia),sizeof(ia),0);
    
    	ia.sin_family      = AF_INET;
    	ia.sin_port        = htons(26666);
    	ia.sin_addr.s_addr = ::inet_addr("127.0.0.1");
    
    	protoent* protocol = ::getprotobyname("tcp");
    	int fd = ::socket(AF_INET,SOCK_STREAM,protocol->p_proto);
    	if ( fd < 0 )
    		quit(strerror(errno));
    
    	// ist der socket verbunden wartet select auf daten;
    	// ohne connect kehrt select sofort zurueck, beim
    	// lesen vom socket erhalte ich dann (verstaendlicherweise)
    	// "transport endpoint is not connected". warum?
    	/*if ( ::connect(fd,(sockaddr*)&ia,sizeof(ia)) < 0 )
    		quit(strerror(errno));*/
    
    	fd_set readfds;
    	FD_ZERO(&readfds);
    	FD_SET(fd,&readfds);
    
    	int s = select(fd+1,&readfds,0,0,0);
    	if ( s < 0 )
    		quit(strerror(errno));
    
    	if ( FD_ISSET(fd,&readfds) )
    	{
    		char buffer[10];
    		int r = read(fd,buffer,sizeof(buffer));
    		if ( r < 0 )
    			quit(strerror(errno));
    		else
    			quit("FD_ISSET(fd,&readfds)");
    	}
    	else
    		quit("!FD_ISSET(fd,&readfds)");
    }
    


  • Worauf soll denn ein blockierendes select() sinnvoll warten in deinem Fall?

    Wenn du selbst eine Verbindung aufbauen willst, fehlt dir noch ein bind() und ein connect(), bevor du Daten schreiben und lesen kannst.

    Wenn du auf Verbindungen wartest, so fehlt dir noch ein bind() und listen() bevor du mit select auf Verbindungen warten kannst. Wenn select() dann zurückkehrt, ist aber erst ein accept() notwendig, bevor du Daten lesen darfst.



  • hmm. meine frage zielte eher darauf hin ab, ob das verhalten von select
    auf einen nicht verbundenen socket definiert ist. unter windows xp
    blockiert ein select naemlich auch auf einen nicht verbundenen socket.

    aber ich denke du hast recht mit "worauf select warten soll". wahrscheinlich
    ist es eine eigenart der windows-sockets.

    und ein bind vor dem connect brauch ich nich, da mir der client socket egal ist.
    oder wie meinst du das?



  • Wenn man selbst verbinden will, dann ist ein bind nicht notwendig, das stimmt schon.


Anmelden zum Antworten