浏览代码

Added Socket.Connected.

Mark Sibly 8 年之前
父节点
当前提交
3727aba49f

+ 52 - 0
modules/std/socket/native/socket.cpp

@@ -436,6 +436,8 @@ namespace bbSocket{
 			setsockopt( socket,SOL_SOCKET,SO_SNDTIMEO,ip,sz );
 		}else if( name=="SO_RCVTIMEO" ){
 			setsockopt( socket,SOL_SOCKET,SO_RCVTIMEO,ip,sz );
+		}else if( name=="SO_BROADCAST" ){
+			setsockopt( socket,SOL_SOCKET,SO_BROADCAST,ip,sz );
 		}
 	}
 	
@@ -454,6 +456,8 @@ namespace bbSocket{
 			getsockopt( socket,SOL_SOCKET,SO_SNDTIMEO,ip,(socklen_t*)&sz );
 		}else if( name=="SO_RCVTIMEO" ){
 			getsockopt( socket,SOL_SOCKET,SO_RCVTIMEO,ip,(socklen_t*)&sz );
+		}else if( name=="SO_BROADCAST" ){
+			getsockopt( socket,SOL_SOCKET,SO_BROADCAST,ip,(socklen_t*)&sz );
 		}
 		
 		return value;
@@ -474,4 +478,52 @@ namespace bbSocket{
 		return getnameinfo( (const sockaddr*)addr,addrlen,host,1023,service,79,0 );
 	}
 	
+	int select( int n_read,int *r_socks,int n_write,int *w_socks,int n_except,int *e_socks,int millis ){
+	
+		fd_set r_set,w_set,e_set;
+		
+		int n=-1;
+		
+		FD_ZERO( &r_set );
+		for( int i=0;i<n_read;++i ){
+			FD_SET( r_socks[i],&r_set );
+			if( r_socks[i]>n ) n=r_socks[i];
+		}
+		FD_ZERO( &w_set );
+		for( int i=0;i<n_write;++i ){
+			FD_SET( w_socks[i],&w_set );
+			if( w_socks[i]>n ) n=w_socks[i];
+		}
+		FD_ZERO( &e_set );
+		for( int i=0;i<n_except;++i ){
+			FD_SET( e_socks[i],&e_set );
+			if( e_socks[i]>n ) n=e_socks[i];
+		}
+		
+		struct timeval tv,*tvp;
+			
+		if( millis<0 ){
+			tvp=0;
+		}else{
+			tv.tv_sec=millis/1000;
+			tv.tv_usec=(millis%1000)*1000;
+			tvp=&tv;
+		}
+		
+		int r=select( n+1,&r_set,&w_set,&e_set,tvp );
+		if( r<0 ) return r;
+		
+		for( int i=0;i<n_read;++i ){
+			if( !FD_ISSET(r_socks[i],&r_set) ) r_socks[i]=0;
+		}
+		for( int i=0;i<n_write;++i ){
+			if( !FD_ISSET(w_socks[i],&w_set) ) w_socks[i]=0;
+		}
+		for( int i=0;i<n_except;++i ){
+			if( !FD_ISSET(e_socks[i],&e_set) ) e_socks[i]=0;
+		}
+		
+		return r;
+	}
+	
 }

+ 2 - 0
modules/std/socket/native/socket.h

@@ -37,6 +37,8 @@ namespace bbSocket{
 	int getpeeraddr( int socket,void *sockaddr,int *addrlen );
 
 	int sockaddrname( const void *sockaddr,int addrlen,char *host,char *service );
+	
+	int select( int n_read,int *r_socks,int n_write,int *w_socks,int n_except,int *e_socks,int millis );
 }
 
 #endif

+ 20 - 2
modules/std/socket/socket.monkey2

@@ -74,6 +74,10 @@ Function socket_getpeeraddr:Int( socket:Int,addr:Void Ptr,addrlen:Int Ptr )="bbS
 #end
 Function socket_sockaddrname:Int( addr:Void Ptr,addrlen:Int,host:libc.char_t Ptr,service:libc.char_t Ptr )="bbSocket::sockaddrname"
 
+#rem monkeydoc @hidden
+#end
+Function socket_select:Int( n_read:Int,r_socks:Int ptr,n_write:Int,w_socks:Int Ptr,n_except:Int,e_socks:Int Ptr,millis:Int )="bbSocket::select"
+	
 Public
 
 #rem monkeydoc The SocketType enum.
@@ -222,11 +226,25 @@ Class Socket Extends std.resource.Resource
 	End
 	#end
 	
-	#rem  monkeydoc True if socket has been closed
+	#rem  monkeydoc True if socket has been closed.
 	#end
 	Property Closed:Bool()
 		Return _socket=-1
 	End
+
+	#rem monkeydoc True if socket is connected to peer.
+	#end
+	Property Connected:bool()
+		If _socket=-1 Return False
+
+		Local read:=_socket
+		
+		Local r:=socket_select( 1,Varptr read,0,Null,0,Null,0 )
+		
+		If r=1 Return socket_canrecv( _socket )<>0
+		
+		Return r=0
+	End
 	
 	#rem monkeydoc The number of bytes that can be received from the socket without blocking.
 	#end
@@ -298,7 +316,7 @@ Class Socket Extends std.resource.Resource
 	
 	Returns the number of bytes actually written.
 	
-	Can return less than `sizet` if the socket has been closed by the peer or if an error occured.
+	Can return less than `size` if the socket has been closed by the peer or if an error occured.
 	
 	@param buf The memory buffer to write data from.
 	

+ 1 - 1
modules/std/socket/socketstream.monkey2

@@ -29,7 +29,7 @@ Class SocketStream Extends std.stream.Stream
 	#end
 	Property Eof:Bool() Override
 
-		Return _socket.Closed
+		Return Not _socket.Connected
 	End
 
 	#rem monkeydoc Always 0.