ADOBE/ ActionScript

[AS] adobe 액션스크립트 소켓 타임 아웃 관련

AlrepondTech 2020. 9. 22. 04:11
반응형

 

 

 

 

 

=================================

=================================

=================================

 

 

 

 

 

 

 

 

2. 소켓 타임아웃
액 션스크립트에서 Socket, XMLSocket의 모든 securityError이벤트는 connect()메서드의 호출 이후 일정시간 경과후 발생하게 됩니다. 이것은 송출 이후 즉각적인 securityError가 더 늦게 발생하게 되며, 또한 더 일찍 연결에 성공하게되면 securityError 이벤트는 긴 딜레이가 발생하게 됩니다. 그래서, 20초의 소켓 타임아웃을 정해 두었습니다. 물론, 개발자들은 Socket.timeout과 XMLSocket.timeout를 통해서 이 시간을 조정할 수 있습니다.

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://yahon.tistory.com/15

 

Socket에서 Connect Timeout 관리 하기

지식/Network 2007/06/15 17:01

[질문]connect Timeout 시간을 줄이는 방법은?

[답변1]connect 함수를 호출하기 전에 NONBLOCK 옵션을 주세요

 

    org_flags = fcntl(sock, F_GETFL, 0);
    flags = org_flags | O_NONBLOCK;
    fcntl(sock, F_SETFL, flags);

 

    if (connect (sock, (struct sockaddr *)&saddr, sizeof (struct sockaddr_in)) < 0)
    {
        close( sock );
        return -1;
    }

 

    fcntl(sock, F_SETFL, org_flags);

 

이렇게 하면 바로 한번의 연결을 시도한 후 실패하면 바로 리턴 합니다

 

local(127.0.0.1)에 접속하는 경우는 이렇게 사용하면 되구요
외부에 연결하는 경우에는 select를 써서 약간 시간동안 
연결을 기다리게 해 줄 수 있습니다.

 


[답변2]alarm interrupt 사용

 

오래전에 썼던 방법인데.. 기억은 가물가물..
함 테스트 해보세요~

 

대충이론은
몇초후에 스스로에게 interrupt를 걸게 하는 겁니다.
커넥트가 성공하면 interrupt걸게 해놨던거를 취소하구요
취소가 안되고 몇초가 지나면 인터럽트 걸려서 프로그램이 죽겠져
alarm 이라는 함수가 그 몇초후에 interrupt를 걸수 있게 해 준다고 합니다.

 

제 소스의 일부를 발췌합니다.

 

    signal(SIGALRM,sig_alarm);
    alarm(5); // 5초 후 스스로에게 interrupt를 건다.

 

    if( (n=connect(s, (struct sockaddr *) &sin, sizeof(sin))) < 0) {
        if(errno == EINTR) {
            errno = ETIMEDOUT;
            printf("was interrupted\n");
        }
        close(s);
        err_msg("Can't connect the server..");
    }
    alarm(0); // 이전 alarm request를 취소 

이상 끝.

 

출처: http://www.unix.co.kr

 

 

 

=================================

=================================

=================================

 

 

출처: http://www.newgrounds.com/bbs/topic/1320518

 

As3: Sockets (adobe Air Style)Oct. 7th, 2012 @ 10:51 PMReply


---
AS3: Main
---

---
Category: Advanced
---

--- AS3: Sockets (Adobe AIR Style) ---

First thing's first: If you don't have it already, grab FlashDevelop

1. Project->New Project
2. Select "AIR AS3 Projector"
3. Name it whatever
4. Double-Click "Main.as" from the "src" folder in the "Project" tab on the far right
5. Create a new class called "Server" (right-click "src" folder, Add->New Class)
6. Create a new class called "Client"

We'll want to have the server running before we try to make connections to it (herp) so we'll do that first.

Open up Server.as and make these functions:

public function init():void{
	//this function initializes the server. We call this in Main
}
public function destroy():void{
	//this function destructs the server safely. We also call this in Main
}

public function checkTimers():void{
	//this function checks to see if it's time to do a bunch of things
}

private function onConnect(e:ServerSocketConnectEvent):void{
	//this is the function that runs automatically when someone connects to the server
}
private function onData(e:ProgressEvent):void{
	//this function runs when data is received
}

private function sortData(data:Object, address:String):void{
	//we use this function to sort through the data and figure out what to do with it
}
private function socketWrite(data:Object, address:String):void{
	//this function is used to send data back to the client, if necessary.
}

and these vars:

public var ready:Boolean = false; //this boolean flag just tells us when the server socket is ready to receive data

private var _socket:ServerSocket = new ServerSocket(); //this is the actual socket

private var _clients:Vector.<Socket> = new Vector.<Socket>; //this vector holds all the clients
private var _addresses:Vector.<String> = new Vector.<String>; //this vector holds all the addresses. It's faster than an address lookup through an array of objects

 

let's initialize the server:

public function init():void{
	_server.addEventListener(ServerSocketConnectEvent.CONNECT, onConnect); //this adds the event listener that gets client connections
	
	try{
		_socket.bind(7678); //this makes the server listen for data on port 7678. Obviously you can change this
	}catch(e:RangeError){
		trace("-Server- " + e.message); //here to stop the program from fataling
		return; //you shall not pass!
	}catch (e:ArgumentError) {
		trace("-Server- " + e.message); //here to stop the program from fataling
		return; //you shall not pass!
	}catch (e:IOError) {
		trace("-Server- " + e.message); //here to stop the program from fataling
		return; //you shall not pass!
	}
	
	try{
		_socket.listen(); //this actually starts the server
	}catch (e:RangeError) {
		trace("-Server- " + e.message); //here to stop the program from fataling
		return; //you shall not pass!
	}catch (e:IOError) {
		trace("-Server- " + e.message); //here to stop the program from fataling
		return; //you shall not pass!
	}
	
	_timers[0] = getTimer(); //used for client checking later
	
	ready = true; //server's ready
	
	trace("-Server- Listening..."); //tell us!
}

and in next logical order, the connection event:

private function onConnect(e:ServerSocketConnectEvent):void {
	for (var i:uint = 0; i < _addresses.length; ++i){ //going through the array to see if we already have that client. Don't want to listen to the same computer twice!
		if (e.socket.remoteAddress == _addresses[i]) { //looks like we already have it
			return; //so we just quit right here
		}
	}
	
	_clients[_addresses.length] = e.socket; //add all the juicy socket stuff to the vector
	_addresses[_addresses.length] = e.socket.remoteAddress; //add the address to another vector. Again, this is much faster than going through all the objects
	_clients[_addresses.length-1].addEventListener(ProgressEvent.SOCKET_DATA, onData); //add the event listener to receive data
}

and now to get some data!

private function onData(e:ProgressEvent):void {
	if (e.target.bytesAvailable > 0) { //make sure we actually have something to read
		try{
			var data:Object = e.target.readObject(); //read the data
		}catch (error:EOFError) {
			trace("-Server- Bad data from " + e.target.remoteAddress + ": " + error.message); //make sure the client can't crash the server
			return; //you shall not pass!
		}catch (error:IOError) {
			trace("-Server- Warning: Bad data from " + e.target.remoteAddress + ": " + error.message);//make sure the client can't crash the server
			return; //you shall not pass!
		}
		
		if(!data.action || !(data.action is String)){ //bad data. Don't process it because it doesn't ask us to do anything
			return; //you shall not pass!
		}
		
		sortData(data, e.target.remoteAddress); //now go through the data and do stuff
	}
}

and now we go through the data:

private function sortData(data:Object, address:String):void {
	var action:String = String(data.action).toLowerCase();
	
	if ("action" == "getHello") {
		data.data = "Well, hello, thar! :3";
		socketWrite(data, address);
	}
}

and finally we return what we've got:

private function socketWrite(input:Object, address:String):void {
	for (var i:uint = 0; i < _addresses.length; ++i) { //go through the addresses just in case we're getting "ghost" data
		if (_addresses[i] == address) { //found our guy!
			break; //break it here, I want to use that i
		}
	}
	
	if (i == _addresses.length - 1 && _addresses[i] != address) { //just in case the break was never called, check the last
		trace("-Server- Recieved data from " + address + " without prior connection");
		return; //you shall not pass!
	}
	
	if (_clients[i] == null || !_clients[i].connected) { //in case the client disconnected somewhere while we were processing
		_clients[i].removeEventListener(ProgressEvent.SOCKET_DATA, onData); //remove the event listener
		_clients = _clients.splice(i, 1); //remove the client
		_addresses = _addresses.splice(i, 1); //remove the address
		return; //you shall not pass!
	}
	
	try {
		_clients[i].writeObject(input); //write the data back to the client
		_clients[i].flush(); //flush the data, in case the system doesn't autoflush it for us
	}catch (error:IOError) {
		trace("-Server- " + error.message); //make sure we don't crash
		return; //you shall not pass!
	}
}

and now we check the timers for events:

public function checkTimers():void {
	var i:uint; //gimme an i! Gimme a... Oh, wait, that's it...
	var timer:int = getTimer(); //grab the current time
	
	if (timer - _timers[0] >= 30000) { //check the clients to see if they're all still there every 30 seconds
		for (i = 0; i < _addresses.length; ++i){ //go through the addresses
			if (!_clients[i].connected) { //we found one that's not connected
				_clients[i].removeEventListener(ProgressEvent.SOCKET_DATA, onData); //remove the listener
				_clients = _clients.splice(i, 1); //remove the client
				_addresses = _addresses.splice(i, 1); //remove the address
			}
		}
		_timers[0] = getTimer(); //reset the timer
	}
}

and now to destroy our creation:

public function destroy():void {
	if(ready){ //make sure we don't try to close it twice
		ready = false; //the server is no longer ready to accept connections because it's shutting down
		
		while(_addresses.length > 0){ //go through the addresses
			_clients[0].removeEventListener(ProgressEvent.SOCKET_DATA, onData); //remove the listener
			_clients = _clients.splice(0, 1); //remove the client
			_addresses = _addresses.splice(0, 1); //remove the address
		}
		
		if (_server.listening) { //make sure the server's actually listening before we try to stop it. Herp.
			try{
				_server.close(); //close the socket
			}catch (e:Error) {
				trace("-Server- " + e.message); //catch the error that probably will never come
			}
		}
	}
}

Programming stuffs (tutorials and extras)
PM me (instead of MintPaw) if you're confuzzled.
thank Skaren for the sig :P

egg82egg82

  • Member since:Jun. 24, 2006
  • Offline.

Forum StatsMemberLevel 05Game Developer

Response to As3: Sockets (adobe Air Style)Oct. 7th, 2012 @ 11:15 PMReply


And now the client. The client is much simpler than the server, so no worries there.

--- Client.as ---

It's kinda the same setup.

public function init():void {
	//initialize
}
public function destroy():void {
	//destroy
}

public function socketWrite(data:Object):void {
	//write
}

private function onConnect(e:Event):void {
	//connected to server
}
private function onData(e:Event):void {
	//received data
}
private function onClose(e:Event):void {
	//server closed the socket
}
public function onError(e:Event):void {
	//oops!
}
private function onTimeout(e:TimerEvent):void {
	//connection timeout
}

private function sortData(data:Object):void{
	//sort the data
}
public var ready:Boolean = false;

private var _timer:Timer = new Timer(5000, 1);
private var _socket:Socket = new Socket();

first thing's first, we gotta initialize the client:

private function init():void {
	_socket.addEventListener(Event.CLOSE, onClose); //what if the server says "no"?
	_socket.addEventListener(Event.CONNECT, onConnect); //ah, we connected!
	_socket.addEventListener(IOErrorEvent.IO_ERROR, onError); //aww, we gots an error 3:
	_socket.addEventListener(ProgressEvent.SOCKET_DATA, onData); //yay, data!
	
	_timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimeout); //socket timeout
	_timer.start(); //start the timer
	
	try {
		_socket.connect("127.0.0.1", 7678); //connect to us on this port. Obviously can be changed.
	}catch (e:IOError) {
		_timer.reset(); //reset the timer so we don't go through timeout as well
		trace("-Client- " + e.message); //oops!
	}catch (e:SecurityError) {
		_timer.reset(); //reset the timer so we don't go through timeout as well
		trace("-Client- " + e.message); //oops!
	}
}

now: CONNECT!

private function onConnect(e:Event):void {
	_timer.reset(); //reset the timer so we don't go through timeout
	ready = true; //we're ready!
	trace("-Connect- Socket connected");
}

on nom nom, data!

private function onData(e:Event):void {
	_timer.reset(); //reset the timer so we don't go through timeout
	
	if (_socket.bytesAvailable > 0) { //make sure there's something to read
		try {
			var data:Object = _socket.readObject(); //read the data!
		}catch (e:EOFError) {
			trace("-Client- " + e.message); //what- how?
			return; //you shall not pass!
		}catch (e:IOError) {
			trace("-Client- " + e.message); //now this one I can see
			return; //you shall not pass!
		}
		
		sortData(data); //sort our data. No, we're not checking for bad data this time
	}
}

now let's sort the data:

private function sortData(data:Object):void {
	if (data.action == "getHello") {
		trace("Server said: " + data.data);
	}
}

server closed the connection? Whaaa?

private function onClose(e:Event):void {
	_timer.reset(); //reset the timer
	ready = false; //client is NOT ready!
	trace("-Client- Server closed connection"); //noooo.... Whaaaiii?!?
}

in case of error, run function:

private function onError(e:IOErrorEvent):void {
	_timer.reset(); //reset the timer
	trace("-Client- " + e.text); //oh, damn.
}
private function onTimeout(e:TimerEvent):void {
	destroy(); //remove the socket. Obviously something's wrong.
	trace("-Client- Read timeout"); //log it
}

and now to destroy our creation:

public function destroy():void {
	if (ready) { //don't want to accidentally run this again!
		ready = false; //client is NOT ready!
		
		_timer.stop(); //stop the timer
		
		if (_socket.connected) { //if we're connected, do stuff!
			_socket.removeEventListener(Event.CLOSE, onClose); //remove the listener
			_socket.removeEventListener(Event.CONNECT, onConnect); //remove the listener
			_socket.removeEventListener(IOErrorEvent.IO_ERROR, onError); //remove the listener
			_socket.removeEventListener(ProgressEvent.SOCKET_DATA, onData); //remove the listener
			
			_timer.removeEventListener(TimerEvent.TIMER_COMPLETE, onTimeout); //remove the listener
			
			try {
				_socket.close(); //close the socket
			}catch (e:IOError) {
				trace("-Client- " + e.message); //ya never know!
				return; //you shall not pass!
			}
		}
	}
}

Programming stuffs (tutorials and extras)
PM me (instead of MintPaw) if you're confuzzled.
thank Skaren for the sig :P

egg82egg82

  • Member since:Jun. 24, 2006
  • Offline.

Forum StatsMemberLevel 05Game Developer

Response to As3: Sockets (adobe Air Style)Oct. 7th, 2012 @ 11:35 PMReply


--- Client.as ctnd. ---

forgot the socketWrite function!

public function socketWrite(data:Object):void {
	try {
		_socket.writeObject(data); //write the data to the socket (server)
		_socket.flush(); //flush the socket just in case the OS doesn't do that for us
	}catch(e:IOError) {
		trace("-Client- " + e.message); //damn!
		return; //you shall not pass!
	}
	
	_timer.start(); //start the timeout timer
}

finally, in Main.as just wait for the server and client, and send the data after everything's connected.

--- Main.as ---

private var _server:Server;
private var _client:Client;
private function init(e:Event = null):void {
	removeEventListener(Event.ADDED_TO_STAGE, init);
	
	_server = new Server();
	addEventListener(Event.ENTER_FRAME, serverWait);
}

private function serverWait(e:Event):void{
	if(_server.ready){
		removeEventListener(Event.ENTER_FRAME, serverWait);
		
		_client = new Client();
		addEventListener(Event.ENTER_FRAME, clientWait);
	}
}

private function clientWait(e:Event):void{
	if(_client.ready){
		removeEventListener(Event.ENTER_FRAME, clientWait);
		
		var data:Object = new Object();
		data.action = "getHello";
		_client.socketWrite(data);
	}
}

Programming stuffs (tutorials and extras)
PM me (instead of MintPaw) if you're confuzzled.
thank Skaren for the sig :P

egg82egg82

  • Member since:Jun. 24, 2006
  • Offline.

Forum StatsMemberLevel 05Game Developer

Response to As3: Sockets (adobe Air Style)Oct. 8th, 2012 @ 12:06 PMReply


I typed all of this out in the posting box (some copypasta from an old project), so there's probably an error or two in there.

one of them is a coding error (my fault) - the application will freeze on shutdown if you're using a server.

in Server.as's destroy() function, change:

while(_addresses.length > 0){ //go through the addresses
			_clients[0].removeEventListener(ProgressEvent.SOCKET_DATA, onData); //remove the listener
			_clients = _clients.splice(0, 1); //remove the client
			_addresses = _addresses.splice(0, 1); //remove the address
		}

to

for (var i:uint = 0; i < _addresses.length; i++) { //go through the addresses
			_clients[i].removeEventListener(ProgressEvent.SOCKET_DATA, onData); //remove the listener
		}
		_clients = new Vector.<Socket>; //overwrite the clients with a new vector
		_addresses = new Vector.<String>; //overwrite the clients with a new vector

also, apparently i'm unfamiliar with how AS3's splice() function works with vectors. Could have sworn it returned a new vector with the data cut out...


Programming stuffs (tutorials and extras)
PM me (instead of MintPaw) if you're confuzzled.
thank Skaren for the sig :P

 

 

 

=================================

=================================

=================================

 

 

반응형