=================================
=================================
=================================
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.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
- Member since:Jun. 24, 2006
- Offline.
- Send Private Message
- Browse All Posts (3,007)
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
- Member since:Jun. 24, 2006
- Offline.
- Send Private Message
- Browse All Posts (3,007)
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
- Member since:Jun. 24, 2006
- Offline.
- Send Private Message
- Browse All Posts (3,007)
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
=================================
=================================
=================================