Created
March 18, 2016 09:31
-
-
Save zwetan/565109f1138cac00795e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package flash.net | |
{ | |
import C.arpa.inet.*; | |
import C.errno.*; | |
import C.netdb.*; | |
import C.netinet.*; | |
import C.sys.socket.*; | |
import C.unistd.*; | |
import flash.utils.ByteArray; | |
public class Socket | |
{ | |
private var _connected:Boolean; | |
private var _sockfd:int; | |
private var _info:addrinfo; | |
private var _addrlist:Array; | |
private var _errors:Array; | |
private var _localAddress:String; | |
private var _localPort:int; | |
private var _remoteAddress:String; | |
private var _remotePort:int; | |
private var _remoteAddresses:Array; | |
/** | |
* Function hook for the "connect" event. | |
*/ | |
public var onConnect:Function;/* = function():void | |
{ | |
trace( "onConnect()" ); | |
}*/ | |
/** | |
* Function hook for the "disconnect" event. | |
*/ | |
public var onDisconnect:Function;/* = function():void | |
{ | |
trace( "onDisconnect()" ); | |
}*/ | |
public function Socket( host:String = null, port:int = 0 ) | |
{ | |
super(); | |
_reset(); | |
if( host != null ) | |
{ | |
this.connect( host, port ); | |
} | |
} | |
private function _reset():void | |
{ | |
_connected = false; | |
_sockfd = -1; | |
_info = null; | |
_addrlist = null; | |
_errors = []; | |
_localAddress = ""; | |
_localPort = -1; | |
_remoteAddress = ""; | |
_remotePort = -1; | |
_remoteAddresses = null; | |
} | |
private function _findLocalAddressAndPort():void | |
{ | |
if( _info.ai_family == AF_INET ) | |
{ | |
_findLocalAddressAndPort4(); | |
} | |
else | |
{ | |
_findLocalAddressAndPort6(); | |
} | |
} | |
private function _findLocalAddressAndPort4():void | |
{ | |
var addr:sockaddr_in = new sockaddr_in(); | |
var result:int = getsockname( _sockfd, addr ); | |
if( result == -1 ) | |
{ | |
var e:CError = new CError( "", errno ); | |
_errors.push( e ); | |
} | |
else | |
{ | |
var a:String = inet_ntop( addr.sin_family, addr ); | |
if( !a ) | |
{ | |
var e:CError = new CError( "", errno ); | |
_errors.push( e ); | |
return; | |
} | |
else | |
{ | |
_localAddress = a; | |
} | |
_localPort = ntohs( addr.sin_port ); | |
} | |
} | |
private function _findLocalAddressAndPort6():void | |
{ | |
var addr:sockaddr_in6 = new sockaddr_in6(); | |
var result:int = getsockname( _sockfd, addr ); | |
if( result == -1 ) | |
{ | |
var e:CError = new CError( "", errno ); | |
_errors.push( e ); | |
} | |
else | |
{ | |
var a:String = inet_ntop( addr.sin6_family, addr ); | |
if( !a ) | |
{ | |
var e:CError = new CError( "", errno ); | |
_errors.push( e ); | |
return; | |
} | |
else | |
{ | |
_localAddress = a; | |
} | |
_localPort = ntohs( addr.sin6_port ); | |
} | |
} | |
private function _listRemoteAddresses():Array | |
{ | |
var addresses:Array = []; | |
if( !_addrlist ) { return addresses; } | |
var i:uint; | |
var info:addrinfo; | |
for( i = 0; i < _addrlist.length; i++ ) | |
{ | |
info = _addrlist[i]; | |
addresses.push( inet_ntop( info.ai_family, info.ai_addr ) ); | |
} | |
return addresses; | |
} | |
//private native function internalConnect(host:String, port:int):void; | |
private function _internalConnect( host:String, port:int ):void | |
{ | |
var hostname:String = host; | |
var hostport:String = String( port ); | |
var hints:addrinfo = new addrinfo(); | |
hints.ai_socktype = SOCK_STREAM; | |
hints.ai_family = AF_UNSPEC; | |
var eaierr:CEAIrror = new CEAIrror(); | |
var addrlist:Array = getaddrinfo( hostname, hostport, hints, eaierr ); | |
if( !addrlist ) | |
{ | |
_errors.push( eaierr ); | |
return; | |
} | |
_addrlist = addrlist; | |
var i:uint; | |
var info:addrinfo; | |
var sockfd:int; | |
var result:int; | |
for( i = 0; i < addrlist.length; i++ ) | |
{ | |
info = addrlist[i]; | |
sockfd = C.sys.socket.socket( info.ai_family, info.ai_socktype, info.ai_protocol ); | |
if( sockfd < 0 ) | |
{ | |
var e:CError = new CError( "", errno ); | |
_errors.push( e ); | |
return; | |
} | |
result = C.sys.socket.connect( sockfd, info.ai_addr ); | |
if( result < 0 ) | |
{ | |
var e:CError = new CError( "", errno ); | |
_errors.push( e ); | |
return; | |
} | |
break; | |
} | |
_info = info; | |
var a:String = inet_ntop( _info.ai_family, _info.ai_addr ); | |
if( !a ) | |
{ | |
var e:CError = new CError( "", errno ); | |
_errors.push( e ); | |
} | |
else | |
{ | |
_remoteAddress = a; | |
} | |
if( _info.ai_family == AF_INET ) | |
{ | |
// IPv4 | |
_remotePort = ntohs( _info.ai_addr.sin_port ); | |
} | |
else | |
{ | |
// IPv6 | |
_remotePort = ntohs( _info.ai_addr.sin6_port ); | |
} | |
_sockfd = sockfd; | |
} | |
public function connect( host:String, port:int ):void | |
{ | |
trace( "connect: host="+host+", port="+port ); | |
_internalConnect( host, port ); | |
if( _sockfd == -1 ) | |
{ | |
trace( "Could not connect to " + host + ":" + port ); | |
return; | |
} | |
else | |
{ | |
_connected = true; | |
_findLocalAddressAndPort(); | |
if( onConnect ) { this.onConnect(); } | |
} | |
} | |
//private native function internalClose():void; | |
private function _internalClose():void | |
{ | |
if( !_connected ) | |
{ | |
/* NOTE | |
never connected | |
or already disconnected | |
*/ | |
return; | |
} | |
var result:int = C.unistd.close( _sockfd ); | |
if( result == -1 ) | |
{ | |
var e:CError = new CError( "", errno ); | |
_errors.push( e ); | |
return; | |
} | |
if( onDisconnect ) { this.onDisconnect(); } | |
_reset(); | |
} | |
public function close():void | |
{ | |
_internalClose(); | |
} | |
public function toDebugString():String | |
{ | |
//trace( "HttpConnection.toString()" ); | |
var str:String = ""; | |
str += "{Socket"; | |
if( _connected ) | |
{ | |
str += " connected:"; | |
str += " " + _localAddress; | |
str += ":" + _localPort; | |
str += " =>"; | |
str += " " + _remoteAddress; | |
str += ":" + _remotePort; | |
} | |
else | |
{ | |
str += " disconnected"; | |
} | |
str += " "; | |
str += "}"; | |
return str; | |
} | |
} | |
} |
Usage
build the lib
$ redbean
test the list
$ ./test_flashnet
output should be
flahs_net 0.1 loaded
[object Socket]
connect: host=www.google.com, port=80
onConnect()
{Socket connected: 192.168.0.64:52438 => 216.58.211.100:80 }
onDisconnect()
{Socket connected: 192.168.0.64:52438 => 216.58.211.100:80 }
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
build with redbean
project structure
define include list
flash_net.as
build.as3
test with as3shebang
test_flashnet