소켓

Flash Player 9 이상, Adobe AIR 1.0 이상

소켓은 두 컴퓨터 프로세스 간에 설정되는 네트워크 연결 유형입니다. 일반적으로 동일한 IP(인터넷 프로토콜) 네트워크에 연결된 서로 다른 두 컴퓨터에서 프로세스가 실행됩니다. 그러나 특수한 "로컬 호스트" IP 주소를 사용하면 동일한 컴퓨터에서도 연결된 프로세스를 실행할 수 있습니다.

Adobe Flash Player는 클라이언트측 TCP(전송 제어 프로토콜) 소켓을 지원합니다. Flash Player 응용 프로그램은 소켓 서버 역할을 하는 다른 프로세스에 연결할 수 있지만 다른 프로세스에서 들어오는 연결 요청은 받을 수 없습니다. 즉, Flash Player 응용 프로그램은 TCP 서버에 연결할 수 있지만 TCP 서버 역할은 수행할 수 없습니다.

또한 Flash Player API에도 XMLSocket 클래스가 포함되어 있습니다. XMLSocket 클래스는 Flash Player 전용 프로토콜을 사용하여 해당 프로토콜을 인식하는 서버와 XML 메시지를 교환할 수 있도록 합니다. XMLSocket 클래스는 ActionScript 1에서 도입된 이후 계속 지원되어 이전 버전과의 호환성을 제공합니다. Flash XMLSocket과 통신하기 위해 특별히 만든 서버에 연결하는 경우가 아니라면 Socket 클래스는 일반적으로 새 응용 프로그램에 사용되어야 합니다.

Adobe AIR에는 소켓 기반 네트워크 프로그래밍을 위한 몇 가지 클래스가 추가되었습니다. AIR 응용 프로그램은 ServerSocket 클래스를 사용하여 TCP 소켓 서버 역할을 수행할 수 있으며 SecureSocket 클래스를 사용하여 SSL 또는 TLS 보안이 필요한 소켓 서버에 연결할 수 있습니다. 또한 AIR 응용 프로그램은 DatagramSocket 클래스를 사용하여 UDP(Universal Datagram Protocol) 메시지를 주고 받을 수 있습니다.

TCP 소켓

TCP(Transmission Control Protocol)는 영구 네트워크 연결에서 메시지를 교환할 수 있는 방법을 제공합니다. TCP를 사용할 경우, 심각한 네트워크 문제만 없다면 전송된 모든 메시지가 올바른 순서로 도착합니다. TCP 연결에는 "클라이언트"와 "서버"가 필요합니다. Flash Player에서 클라이언트 소켓을 만들 수 있습니다. 또한 Adobe AIR에서는 서버 소켓을 만들 수 있습니다.

다음 ActionScript API는 TCP 연결을 제공합니다.

  • Socket - 클라이언트 응용 프로그램이 서버에 연결할 수 있도록 해 줍니다. Socket 클래스는 들어오는 연결을 수신할 수 없습니다.

  • SecureSocket(AIR) - 클라이언트 응용 프로그램이 신뢰할 수 있는 서버에 연결하고 암호화된 통신에 참여할 수 있도록 해 줍니다.

  • ServerSocket(AIR) - 응용 프로그램이 들어오는 연결을 수신하고 서버 역할을 할 수 있도록 해 줍니다.

  • XMLSocket - 클라이언트 응용 프로그램이 XMLSocket 서버에 연결할 수 있도록 해 줍니다.

이진 클라이언트 소켓

XML 메시지 교환이 클라이언트와 서버로 제한되지 않는다는 점을 제외하면 이진 소켓 연결도 XML 소켓과 비슷합니다. 대신 연결할 때 이진 정보로 데이터를 전송할 수 있으므로 메일 서버(POP3, SMTP 및 IMAP) 및 뉴스 서버(NNTP)를 비롯한 다양한 서비스에 연결할 수 있습니다.

Socket 클래스

Socket 클래스는 소켓 연결을 만들고 원시 이진 데이터를 읽고 쓸 수 있도록 하며 이진 프로토콜을 사용하는 서버와 상호 운용하는 데 유용합니다. 이진 소켓 연결을 사용하여 POP3, SMTP, IMAP 및 NNTP 같은 여러 가지 인터넷 프로토콜과 상호 작용하는 코드를 작성할 수 있습니다. 이러한 상호 작용으로 응용 프로그램에서 메일 및 뉴스 서버에 연결할 수 있습니다.

Flash Player에서는 서버의 이진 프로토콜을 사용하여 해당 서버와 직접 통신할 수 있습니다. 일부 서버에서는 big-endian 바이트 순서를 사용하는 반면 다른 서버에서는 little-endian 바이트 순서를 사용합니다. "네트워크 바이트 순서"가 big-endian이므로 인터넷에서 대부분의 서버는 big-endian 바이트 순서를 사용합니다. little-endian 바이트 순서가 널리 사용되는 이유는 Intel® x86 아키텍처에서 사용되기 때문입니다. endian 바이트 순서를 선택할 때는 데이터를 보내거나 받는 서버의 바이트 순서와 일치하는 endian 바이트 순서를 사용해야 합니다. IDataInput 및 IDataOutput 인터페이스에서 수행되는 모든 연산과 그러한 인터페이스(ByteArray, Socket 및 URLStream)를 구현하는 클래스는 기본적으로 big-endian 형식으로 인코딩됩니다. 즉, 가장 중요한 바이트가 앞에 옵니다. 이 기본 바이트 순서를 선택한 것은 Java와 공식 네트워크 바이트 순서를 일치시키기 위한 것입니다. big-endian 바이트 순서를 사용할지 또는 little-endian 바이트 순서를 사용할지 변경하려면 endian 속성을 Endian.BIG_ENDIAN 또는 Endian.LITTLE_ENDIAN 으로 설정할 수 있습니다.

Socket 클래스는 IDataInput 및 IDataOutput 인터페이스(flash.utils 패키지에 있음)에서 정의된 모든 메서드를 상속합니다. 소켓에서 쓰기 및 읽기를 수행하려면 이러한 메서드를 사용해야 합니다.

자세한 내용은 다음 항목을 참조하십시오.

보안 클라이언트 소켓(AIR)

SecureSocket 클래스를 사용하여 SSLv4(Secure Sockets Layer 버전 4) 또는 TLSv1(Transport Layer Security 버전 1)을 사용하는 소켓 서버에 연결할 수 있습니다. 보안 소켓은 서버 인증, 데이터 무결성 및 메시지 기밀성의 세 가지 이점을 제공합니다. 런타임은 서버 인증서와 루트에 대한 관계 또는 사용자의 신뢰 저장소에 있는 중간 인증 기관 인증서를 사용하여 서버를 인증합니다. 런타임은 SSL 및 TLS 프로토콜 구현에서 사용되는 암호화 알고리즘을 사용하여 데이터 무결성 및 메시지 기밀성을 제공합니다.

SecureSocket 객체를 사용하여 서버에 연결할 때 런타임은 인증서 신뢰 저장소를 사용하여 서버 인증서의 유효성을 검사합니다. Windows와 Mac의 경우 운영 체제에서 신뢰 저장소를 제공합니다. Linux의 경우 런타임에서 자체 신뢰 저장소를 제공합니다.

서버 인증서가 유효하지 않거나 신뢰할 수 없는 경우 런타임이 ioError 이벤트를 전달합니다. SecureSocket 객체의 serverCertificateStatus 속성을 보면 유효성 검사의 실패 원인을 확인할 수 있습니다. 신뢰할 수 있는 유효한 인증서가 없는 서버와 통신할 때는 저장소가 제공되지 않습니다.

CertificateStatus 클래스는 다음과 같이 가능한 유효성 검사 결과를 나타내는 문자열 상수를 정의합니다.

  • Expired - 인증서 만료 날짜가 지났습니다.

  • Invalid - 여러 가지 이유로 인증서가 유효하지 않을 수 있습니다. 예를 들어 인증서가 수정 또는 손상되었거나 인증서 유형이 올바르지 않을 수 있습니다.

  • Invalid chain - 서버의 인증서 체인에 있는 하나 이상의 인증서가 유효하지 않습니다.

  • Principal mismatch - 서버의 호스트 이름 및 인증서 공통 이름이 일치하지 않습니다. 즉, 서버에서 잘못된 인증서를 사용하고 있습니다.

  • Revoked - 인증서 발행 기관이 인증서를 취소했습니다.

  • Trusted - 인증서가 유효하고 신뢰할 수 있습니다. SecureSocket 객체는 신뢰할 수 있는 유효한 인증서를 사용하는 서버에만 연결할 수 있습니다.

  • Unknown - 아직 SecureSocket 객체의 인증서 유효성을 검사하지 않았습니다. connect() 를 호출하기 전이나 connect 또는 ioError 이벤트가 전달되기 전에는 serverCertificateStatus 속성이 이 상태 값을 가집니다.

  • Untrusted signers - 인증서가 클라이언트 컴퓨터의 신뢰 저장소에 있는 신뢰할 수 있는 루트 인증서에 "연결"되지 않았습니다.

SecureSocket 객체와 통신하려면 서버에서 보안 프로토콜을 사용하고, 서버에 신뢰할 수 있는 유효한 인증서가 있어야 합니다. 이 점 외에는 SecureSocket 객체를 사용하는 것과 Socket 객체를 사용하는 것이 동일합니다.

SecureSocket 객체는 일부 플랫폼에서 지원되지 않습니다. 런타임이 현재 클라이언트 컴퓨터에서 SecureSocket 객체 사용을 지원하는지 여부를 테스트하려면 SecureSocket 클래스의 isSupported 속성을 사용하십시오.

자세한 내용은 다음 항목을 참조하십시오.

TCP 소켓 예제: Telnet 클라이언트 구축

이 Telnet 예제에서는 Socket 클래스를 사용하여 원격 서버와 연결하고 데이터를 전송하는 기술을 보여 줍니다. 이 예제는 다음과 같은 기술에 대해 설명합니다.

  • Socket 클래스를 사용하여 사용자 정의 Telnet 클라이언트 만들기

  • ByteArray 객체를 사용하여 원격 서버로 텍스트 보내기

  • 원격 서버에서 수신한 데이터 처리

이 샘플에 대한 응용 프로그램 파일을 가져오려면 www.adobe.com/go/learn_programmingAS3samples_flash_kr 을 참조하십시오. Telnet 응용 프로그램 파일은 Samples/Telnet 폴더에 있습니다. 이 응용 프로그램은 다음과 같은 파일로 구성됩니다.

파일

설명

TelnetSocket.fla

또는

TelnetSocket.mxml

Flex(MXML) 또는 Flash(FLA)용 사용자 인터페이스로 구성된 기본 응용 프로그램 파일입니다.

TelnetSocket.as

사용자 인터페이스 논리를 제공하는 문서 클래스입니다(Flash 전용).

com/example/programmingas3/Telnet/Telnet.as

원격 서버에 연결, 데이터 송수신 및 표시 등 응용 프로그램에 대한 Telnet 클라이언트 기능을 제공합니다.

Telnet 소켓 응용 프로그램 개요

기본 TelnetSocket.mxml 파일은 전체 응용 프로그램의 UI(사용자 인터페이스)를 만드는 역할을 합니다.

이 파일은 UI 외에도 login() sendCommand() 라는 두 가지 메서드를 정의하여 지정한 서버에 사용자를 연결합니다.

다음 코드는 기본 응용 프로그램 파일의 ActionScript를 보여 줍니다.

import com.example.programmingas3.socket.Telnet; 
 
private var telnetClient:Telnet; 
private function connect():void 
{ 
    telnetClient = new Telnet(serverName.text, int(portNumber.text), output); 
    console.title = "Connecting to " + serverName.text + ":" + portNumber.text; 
    console.enabled = true; 
} 
private function sendCommand():void 
{ 
    var ba:ByteArray = new ByteArray(); 
    ba.writeMultiByte(command.text + "\n", "UTF-8"); 
    telnetClient.writeBytesToSocket(ba); 
    command.text = ""; 
}

코드의 첫 번째 줄은 사용자 정의 com.example.programmingas.socket 패키지에서 Telnet 클래스를 가져옵니다. 코드의 두 번째 줄은 Telnet 클래스의 인스턴스( telnetClient )를 선언하며 이는 이후 connect() 메서드를 통해 초기화됩니다. 그 다음에 connect() 메서드를 선언하고 앞에서 선언한 telnetClient 변수를 초기화합니다. 이 메서드는 사용자가 지정한 Telnet 서버 이름, Telnet 서버 포트 및 표시 목록의 TextArea 구성 요소에 대한 참조를 전달합니다. 표시 목록은 소켓 서버에서 텍스트 응답을 표시하는 데 사용됩니다. connect() 메서드의 마지막 두 줄은 패널의 title 속성을 설정하고 패널 구성 요소를 사용하도록 설정하여 사용자가 원격 서버에 데이터를 전송할 수 있도록 합니다. 기본 응용 프로그램 파일의 마지막 메서드인 sendCommand() 는 사용자의 명령을 원격 서버에 ByteArray 객체로 전송하는 데 사용됩니다.

Telnet 클래스 개요

Telnet 클래스는 원격 Telnet 서버에 연결하고 데이터를 송수신하는 작업을 담당합니다.

Telnet 클래스는 다음과 같은 전용 변수를 선언합니다.

private var serverURL:String; 
private var portNumber:int; 
private var socket:Socket; 
private var ta:TextArea; 
private var state:int = 0;

첫 번째 변수인 serverURL 에는 연결할 사용자 지정 서버 주소가 포함되어 있습니다.

두 번째 변수인 portNumber 는 현재 실행 중인 Telnet 서버의 포트 번호입니다. 기본적으로 Telnet 서비스는 포트 23에서 실행됩니다.

세 번째 변수인 socket serverURL portNumber 변수에서 정의한 서버에 연결을 시도할 Socket 인스턴스입니다.

네 번째 변수인 ta 는 스테이지의 TextArea 구성 요소 인스턴스에 대한 참조입니다. 이 구성 요소는 원격 Telnet 서버의 응답이나 오류 메시지를 표시하는 데 사용됩니다.

마지막 변수인 state 는 Telnet 클라이언트에서 지원하는 옵션을 결정하는 데 사용되는 숫자 값입니다.

앞에서 보듯이 Telnet 클래스의 생성자 함수는 기본 응용 프로그램 파일의 connect() 메서드에서 호출합니다.

Telnet 생성자는 server , port output 이라는 세 가지 매개 변수를 사용합니다. server port 매개 변수는 Telnet 서버를 실행하는 서버 이름과 포트 번호를 지정합니다. 마지막 매개 변수인 output 은 서버 출력을 사용자에게 표시하는 스테이지의 TextArea 구성 요소 인스턴스에 대한 참조입니다.

public function Telnet(server:String, port:int, output:TextArea) 
{ 
    serverURL = server; 
    portNumber = port; 
    ta = output; 
    socket = new Socket(); 
    socket.addEventListener(Event.CONNECT, connectHandler); 
    socket.addEventListener(Event.CLOSE, closeHandler); 
    socket.addEventListener(ErrorEvent.ERROR, errorHandler); 
    socket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); 
    socket.addEventListener(ProgressEvent.SOCKET_DATA, dataHandler); 
    Security.loadPolicyFile("http://" + serverURL + "/crossdomain.xml"); 
    try 
    { 
        msg("Trying to connect to " + serverURL + ":" + portNumber + "\n"); 
        socket.connect(serverURL, portNumber); 
    } 
    catch (error:Error) 
    { 
        msg(error.message + "\n"); 
        socket.close(); 
    } 
}
소켓에 데이터 기록

소켓 연결에 데이터를 쓰려면 Socket 클래스에서 아무 쓰기 메서드나 호출합니다. 이러한 쓰기 메서드에는 writeBoolean() , writeByte() , writeBytes() , writeDouble() 등이 있습니다. 그런 다음 flush() 메서드를 사용하여 출력 버퍼의 데이터를 플러시합니다. Telnet 서버에서는 바이트 배열을 매개 변수로 가져와 출력 버퍼로 전송하는 writeBytes() 메서드를 사용하여 소켓 연결에 데이터를 기록합니다. writeBytesToSocket() 메서드는 다음과 같습니다.

public function writeBytesToSocket(ba:ByteArray):void 
{ 
    socket.writeBytes(ba); 
    socket.flush(); 
}

이 메서드는 기본 응용 프로그램 파일의 sendCommand() 메서드에 의해 호출됩니다.

소켓 서버의 메시지 표시

소켓 서버에서 메시지를 수신하거나 이벤트가 발생할 때마다 사용자 정의 msg() 메서드가 호출됩니다. 이 메서드는 문자열을 스테이지의 TextArea에 추가하고 사용자 정의 setScroll() 메서드를 호출하여 TextArea 구성 요소가 아래쪽까지 스크롤되도록 합니다. msg() 메서드는 다음과 같습니다.

private function msg(value:String):void 
{ 
    ta.text += value; 
    setScroll(); 
}

TextArea 구성 요소의 내용을 자동으로 스크롤하지 않은 경우 사용자가 서버의 최신 응답을 보려면 텍스트 영역에서 스크롤 막대를 수동으로 드래그해야 합니다.

TextArea 구성 요소 스크롤

setScroll() 메서드에는 TextArea 구성 요소의 내용을 세로로 스크롤하는 ActionScript의 한 행이 포함되어 있으므로 사용자는 반환된 텍스트의 마지막 행을 볼 수 있습니다. 다음 코드 예제는 setScroll() 메서드를 보여 줍니다.

public function setScroll():void 
{ 
    ta.verticalScrollPosition = ta.maxVerticalScrollPosition; 
}

이 메서드는 verticalScrollPosition 속성을 설정합니다. 이 속성은 현재 표시된 문자의 맨 위 행에 대한 행 번호이며 이 번호를 maxVerticalScrollPosition 속성 값으로 설정합니다.

XML 소켓

XML 소켓을 사용하면 명시적으로 닫힐 때까지 열린 상태로 유지되는 원격 서버에 대한 연결을 만들 수 있습니다. 서버와 클라이언트 간에 XML과 같은 문자열 데이터를 교환할 수 있습니다. XML 소켓 서버 사용 시 얻을 수 있는 이점은 클라이언트가 명시적으로 데이터를 요청할 필요가 없다는 것입니다. 서버가 요청을 기다리지 않고 데이터를 전송할 수 있으며, 연결된 모든 클라이언트에 데이터를 전송할 수 있습니다.

Flash Player에서, 그리고 응용 프로그램 샌드박스 외부의 Adobe AIR 내용에서 XML 소켓 연결을 사용하려면 대상 서버에 소켓 정책 파일이 있어야 합니다. 자세한 내용은 웹 사이트 컨트롤(정책 파일) 소켓 연결 을 참조하십시오.

RTMP(Real-Time Messaging Protocol) 프로토콜과 달리, XMLSocket에는 HTTP 터널링 기능이 없기 때문에 XMLSocket 클래스는 자동으로 방화벽을 통해 터널링할 수 없습니다. HTTP 터널링을 사용해야 할 경우 Flash Remoting 또는 Flash Media Server(RTMP 지원)를 대신 사용하십시오.

Flash Player의 내용 또는 응용 프로그램 보안 샌드박스 외부의 AIR 응용 프로그램 내용에서 XMLSocket 객체를 사용하여 서버에 연결할 수 있는 방법과 경우에는 다음과 같은 제한 사항이 적용됩니다.

  • 응용 프로그램 보안 샌드박스 외부에 있는 내용의 경우 XMLSocket.connect() 메서드는 1024 이상의 TCP 포트 번호에만 연결할 수 있습니다. 이 제한 사항 때문에 XMLSocket 객체와 통신하는 서버 데몬 역시 1024 이상의 포트 번호에 할당되어야 합니다. 1024보다 작은 포트 번호는 주로 FTP (21), Telnet (23), SMTP (25), HTTP (80), POP3 (110) 등의 시스템 서비스에 사용되므로 보안 문제 때문에 XMLSocket 객체가 이러한 포트를 사용하지 못하도록 차단됩니다. 이렇게 포트 번호를 제한하면 포트 번호가 잘못 사용될 가능성이 줄어듭니다.

  • 응용 프로그램 보안 샌드박스 외부에 있는 내용의 경우 XMLSocket.connect() 메서드는 내용이 있는 동일한 도메인의 컴퓨터에만 연결할 수 있습니다. 이 제한 사항은 URLLoader.load() 의 보안 규칙과 동일합니다. 내용이 있는 도메인 이외의 도메인에서 실행되는 서버 데몬에 연결하려면 해당 서버에 특정 도메인에서의 액세스를 허용하는 크로스 도메인 정책 파일을 만들면 됩니다. 크로스 도메인 정책 파일에 대한 자세한 내용은 AIR 보안 을 참조하십시오.

참고: XMLSocket 객체와 통신할 서버를 설정하는 작업은 그리 간단하지 않습니다. 응용 프로그램에서 실시간 상호 작용이 필요하지 않은 경우에는 XMLSocket 클래스 대신 URLLoader 클래스를 사용합니다.

XMLSocket 클래스의 XMLSocket.connect() XMLSocket.send() 메서드를 사용하여 소켓 연결을 통해 서버와 XML을 주고받을 수 있습니다. XMLSocket.connect() 메서드는 웹 서버 포트와 소켓 연결을 설정하고, XMLSocket.send() 메서드는 소켓 연결에 지정된 서버에 XML 객체를 전달합니다.

XMLSocket.connect() 메서드를 호출할 때 응용 프로그램은 서버에 대한 TCP/IP 연결을 열고 다음 중 하나가 발생할 때까지 해당 연결을 열린 상태로 유지합니다.

  • XMLSocket 클래스의 XMLSocket.close() 메서드가 호출됩니다.

  • XMLSocket 객체에 대한 참조가 더 이상 존재하지 않습니다.

  • Flash Player가 종료됩니다.

  • 연결이 끊어집니다(예: 모뎀 연결이 끊어짐).

XMLSocket 클래스를 사용하여 서버에 연결

소켓 연결을 만들려면 소켓 연결 요청을 기다리고 Flash Player 또는 AIR 응용 프로그램에 응답을 전송하는 서버측 응용 프로그램을 만들어야 합니다. 이 유형의 서버측 응용 프로그램은 AIR 또는 Java, Python, Perl과 같은 다른 프로그래밍 언어로 작성할 수 있습니다. XMLSocket 클래스를 사용하려면 서버 컴퓨터에서 XMLSocket 클래스가 사용하는 단순 프로토콜을 이해하는 데몬을 실행해야 합니다.

  • XML 메시지는 전이중 TCP/IP 스트림 소켓 연결을 통하여 전송됩니다.

  • 각 XML 메시지는 완전한 XML 문서이며 0바이트로 끝납니다.

  • 단일 XMLSocket 연결에서 송수신할 수 있는 XML 메시지의 수에는 제한이 없습니다.

Java XML 소켓 서버 만들기 및 연결

다음 코드에서는 들어오는 연결을 허용하고 명령 프롬프트 윈도우에 받은 메시지를 표시하는, Java로 작성된 간단한 XMLSocket 서버를 보여 줍니다. 명령줄에서 서버를 시작할 때 다른 포트 번호를 지정할 수 있지만 기본적으로 새로운 서버는 로컬 컴퓨터의 포트 8080에서 만들어집니다.

새 텍스트 문서를 만들고 다음 코드를 추가합니다.

import java.io.*; 
import java.net.*; 
 
class SimpleServer 
{ 
    private static SimpleServer server; 
    ServerSocket socket; 
    Socket incoming; 
    BufferedReader readerIn; 
    PrintStream printOut; 
 
    public static void main(String[] args) 
    { 
        int port = 8080; 
 
        try 
        { 
            port = Integer.parseInt(args[0]); 
        } 
        catch (ArrayIndexOutOfBoundsException e) 
        { 
            // Catch exception and keep going. 
        } 
 
        server = new SimpleServer(port); 
    } 
 
    private SimpleServer(int port) 
    { 
        System.out.println(">> Starting SimpleServer"); 
        try 
        { 
            socket = new ServerSocket(port); 
            incoming = socket.accept(); 
            readerIn = new BufferedReader(new InputStreamReader(incoming.getInputStream())); 
            printOut = new PrintStream(incoming.getOutputStream()); 
            printOut.println("Enter EXIT to exit.\r"); 
            out("Enter EXIT to exit.\r"); 
            boolean done = false; 
            while (!done) 
            { 
                String str = readerIn.readLine(); 
                if (str == null) 
                { 
                    done = true; 
                } 
                else 
                { 
                    out("Echo: " + str + "\r"); 
                    if(str.trim().equals("EXIT")) 
                    { 
                        done = true; 
                    } 
                } 
                incoming.close(); 
            } 
        } 
        catch (Exception e) 
        { 
            System.out.println(e); 
        } 
    } 
 
    private void out(String str) 
    { 
        printOut.println(str); 
        System.out.println(str); 
    } 
}

문서를 하드 디스크에 SimpleServer.java로 저장하고 Java 컴파일러를 사용하여 컴파일하면 SimpleServer.class라는 Java 클래스 파일이 만들어집니다.

명령 프롬프트를 열고 java SimpleServer 를 입력하여 XMLSocket 서버를 시작할 수 있습니다. SimpleServer.class 파일은 로컬 컴퓨터나 네트워크의 어디에나 보관할 수 있으므로 반드시 웹 서버의 루트 디렉토리에 넣지 않아도 됩니다.

파일이 Java 클래스 경로에 없어 서버를 시작할 수 없는 경우 java -classpath . SimpleServer 로 서버를 시작하십시오.

응용 프로그램에서 XMLSocket에 연결하려면 다음과 같이 호스트 이름과 포트 번호를 전달할 때 XMLSocket 클래스의 새 인스턴스를 만들고 XMLSocket.connect() 메서드를 호출해야 합니다.

var xmlsock:XMLSocket = new XMLSocket(); 
xmlsock.connect("127.0.0.1", 8080);

서버에서 데이터를 수신할 때마다 data 이벤트( flash.events.DataEvent.DATA )가 전달됩니다.

xmlsock.addEventListener(DataEvent.DATA, onData); 
private function onData(event:DataEvent):void 
{ 
    trace("[" + event.type + "] " + event.data); 
}

XMLSocket 서버에 데이터를 전송하려면 XMLSocket.send() 메서드를 사용하고 XML 객체나 문자열을 전달합니다. Flash Player가 제공된 매개 변수를 String 객체로 변환하고 XMLSocket 서버에 내용을 전송하고 뒤에 0바이트를 붙입니다.

xmlsock.send(xmlFormattedData);

XMLSocket.send() 메서드는 데이터가 성공적으로 전송되었는지 여부를 나타내는 값을 반환하지 않습니다. 데이터를 보내려고 할 때 오류가 발생하면 IOError 오류가 발생합니다.

XML 소켓 서버에 전송하는 각 메시지는 개행( \n ) 문자로 끝나야 합니다.

자세한 내용은 XMLSocket 을 참조하십시오.

서버 소켓

다른 프로세스가 TCP(Transport Control Protocol) 소켓을 사용하여 응용 프로그램에 연결할 수 있도록 허용하려면 ServerSocket 클래스를 사용합니다. 연결 프로세스는 로컬 컴퓨터 또는 다른 네트워크에 연결된 컴퓨터에서 실행될 수 있습니다. ServerSocket 객체가 연결 요청을 받으면 connect 이벤트를 전달합니다. 이벤트와 함께 전달된 ServerSocketConnectEvent 객체에는 Socket 객체가 포함됩니다. 이 Socket 객체는 이후 다른 프로세스와의 통신에 사용할 수 있습니다.

들어오는 소켓 연결을 수신하려면

  1. ServerSocket 객체를 만들고 로컬 포트에 바인딩합니다.

  2. connect 이벤트에 대한 이벤트 리스너를 추가합니다.

  3. listen() 메서드를 호출합니다.

  4. 들어오는 각 연결에 대한 Socket 객체를 제공공하는 connect 이벤트에 응답합니다.

ServerSocket 객체는 close() 메서드가 호출될 때까지 새 연결을 계속해서 수신합니다.

다음 코드 예제에서는 소켓 서버 응용 프로그램을 만드는 방법을 보여 줍니다. 이 예제에서는 포트 8087에서 들어오는 연결을 수신합니다. 연결이 수신되면 예제에서 메시지(“Connected.” 문자열)가 클라이언트 소켓에 전달됩니다. 그런 다음 서버는 수신되는 모든 메시지를 클라이언트에 다시 전달합니다.

package 
{ 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.events.IOErrorEvent; 
    import flash.events.ProgressEvent; 
    import flash.events.ServerSocketConnectEvent; 
    import flash.net.ServerSocket; 
    import flash.net.Socket; 
     
    public class ServerSocketExample extends Sprite 
    { 
        private var serverSocket:ServerSocket; 
        private var clientSockets:Array = new Array(); 
 
        public function ServerSocketExample() 
        { 
            try 
            { 
                // Create the server socket 
                serverSocket = new ServerSocket(); 
                 
                // Add the event listener 
                serverSocket.addEventListener( Event.CONNECT, connectHandler ); 
                serverSocket.addEventListener( Event.CLOSE, onClose ); 
                 
                // Bind to local port 8087 
                serverSocket.bind( 8087, "127.0.0.1" ); 
                 
                // Listen for connections 
                serverSocket.listen(); 
                trace( "Listening on " + serverSocket.localPort ); 
 
            } 
            catch(e:SecurityError) 
            { 
                trace(e); 
            } 
        } 
 
        public function connectHandler(event:ServerSocketConnectEvent):void 
        { 
            //The socket is provided by the event object 
            var socket:Socket = event.socket as Socket; 
            clientSockets.push( socket ); 
             
            socket.addEventListener( ProgressEvent.SOCKET_DATA, socketDataHandler); 
            socket.addEventListener( Event.CLOSE, onClientClose ); 
            socket.addEventListener( IOErrorEvent.IO_ERROR, onIOError ); 
             
            //Send a connect message 
            socket.writeUTFBytes("Connected."); 
            socket.flush(); 
             
            trace( "Sending connect message" ); 
        } 
         
        public function socketDataHandler(event:ProgressEvent):void 
        { 
            var socket:Socket = event.target as Socket 
                 
            //Read the message from the socket 
            var message:String = socket.readUTFBytes( socket.bytesAvailable ); 
            trace( "Received: " + message); 
 
            // Echo the received message back to the sender 
            message = "Echo -- " + message; 
            socket.writeUTFBytes( message ); 
            socket.flush(); 
            trace( "Sending: " + message ); 
        } 
         
        private function onClientClose( event:Event ):void 
        { 
            trace( "Connection to client closed." ); 
            //Should also remove from clientSockets array... 
        } 
 
        private function onIOError( errorEvent:IOErrorEvent ):void 
        { 
            trace( "IOError: " + errorEvent.text ); 
        } 
 
        private function onClose( event:Event ):void 
        { 
            trace( "Server socket closed by OS." ); 
        } 
}}

자세한 내용은 다음 항목을 참조하십시오.

UDP 소켓(AIR)

UDP(Universal Datagram Protocol)는 상태 비저장 네트워크 연결에서 메시지를 교환할 수 있는 방법을 제공합니다. UDP에서는 메시지가 순서대로 전달되지 않거나 심지어 일부 메시지가 누락될 수도 있습니다. UDP를 사용할 경우 운영 체제의 네트워크 코드에서는 일반적으로 메시지를 마샬링, 추적 및 인식하는 데 시간이 적게 소비됩니다. 따라서 일반적으로 UDP 메시지는 TCP 메시지의 경우보다 더 빨리 대상 응용 프로그램에 도착합니다.

UDP 소켓 통신은 게임에서 위치를 업데이트하거나 음성 채팅 응용 프로그램에서 사운드 패킷을 전달할 때와 같이 실시간 정보를 전송해야 하는 경우에 유용합니다. 이러한 응용 프로그램에서는 일부 데이터 손실도 허용 가능하며, 모든 데이터가 도착하도록 하는 것보다 전송 지연 시간을 짧게 유지하는 것이 중요합니다. 이 외의 거의 모든 다른 용도의 경우 TCP 소켓을 사용하는 것이 더 좋습니다.

AIR 응용 프로그램은 DatagramSocket 및 DatagramSocketDataEvent 클래스에서 UDP 메시지를 보내고 받을 수 있습니다. UDP 메시지를 보내거나 받으려면

  1. DatagramSocket 객체를 만듭니다.

  2. data 이벤트에 대해 이벤트 리스너를 추가합니다.

  3. bind() 메서드를 사용하여 소켓을 로컬 IP 주소 및 포트에 바인딩합니다.

  4. send() 메서드를 호출하고 대상 컴퓨터의 IP 주소 및 포트를 전달하여 메시지를 보냅니다.

  5. data 이벤트에 응답하여 메시지를 받습니다. 이 이벤트에 대해 전달된 DatagramSocketDataEvent 객체에는 메시지 데이터가 들어 있는 ByteArray 객체가 포함됩니다.

다음 코드 예제에서는 응용 프로그램에서 UDP 메시지를 보내고 받는 방법을 보여 줍니다. 이 예제에서는 “Hello.”라는 문자열이 포함된 단일 메시지를 대상 컴퓨터에 보냅니다. 또한 수신되는 모든 메시지의 내용을 추적합니다.

package 
{ 
import flash.display.Sprite; 
import flash.events.DatagramSocketDataEvent; 
import flash.events.Event; 
import flash.net.DatagramSocket; 
import flash.utils.ByteArray; 
 
public class DatagramSocketExample extends Sprite 
{ 
    private var datagramSocket:DatagramSocket; 
     
    //The IP and port for this computer 
    private var localIP:String = "192.168.0.1"; 
    private var localPort:int = 55555; 
     
    //The IP and port for the target computer 
    private var targetIP:String = "192.168.0.2"; 
    private var targetPort:int = 55555; 
     
    public function DatagramSocketExample() 
    { 
        //Create the socket 
        datagramSocket = new DatagramSocket(); 
        datagramSocket.addEventListener( DatagramSocketDataEvent.DATA, dataReceived ); 
         
        //Bind the socket to the local network interface and port 
        datagramSocket.bind( localPort, localIP ); 
         
        //Listen for incoming datagrams 
        datagramSocket.receive(); 
         
        //Create a message in a ByteArray 
        var data:ByteArray = new ByteArray(); 
        data.writeUTFBytes("Hello."); 
         
        //Send the datagram message 
        datagramSocket.send( data, 0, 0, targetIP, targetPort); 
    } 
     
    private function dataReceived( event:DatagramSocketDataEvent ):void 
    { 
        //Read the data from the datagram 
        trace("Received from " + event.srcAddress + ":" + event.srcPort + "> " + 
            event.data.readUTFBytes( event.data.bytesAvailable ) ); 
    } 
}}

UDP 소켓을 사용할 때는 다음과 같은 사항들을 고려하십시오.

  • 데이터의 단일 패킷은 전송자 및 수신자 간의 네트워크 노드 또는 네트워크 인터페이스의 최소 MTU(최대 전송 단위)보다 클 수 없습니다. send() 메서드로 전달된 ByteArray 객체의 모든 데이터는 단일 패킷으로 전송됩니다. TCP의 경우 크기가 큰 메시지는 여러 패킷으로 분할됩니다.

  • 전송자와 대상 간 핸드셰이킹은 지원되지 않습니다. 대상이 존재하지 않거나 지정된 포트에 활성 리스너가 없는 경우 오류 없이 메시지가 삭제됩니다.

  • connect() 메서드를 사용할 경우 다른 소스에서 보낸 메시지는 무시됩니다. UDP 연결은 간단한 패킷 필터링만 제공합니다. 즉, 대상 주소 및 포트에 수신되고 있는 유효한 프로세스가 없을 수도 있습니다.

  • UDP 트래픽은 네트워크 성능을 저하시킬 수 있습니다. 네트워크 정체가 발생할 경우 네트워크 관리자가 서비스 품질 제어 기능을 구현해야 할 수도 있습니다. TCP에는 기본적으로 네트워크 정체 영향을 줄이기 위한 제어 기능이 포함되어 있습니다.

자세한 내용은 다음 항목을 참조하십시오.

IPv6 주소

Flash Player 9.0.115.0 이상에서는 IPv6(Internet Protocol version 6)을 지원합니다. IPv6은 128비트 주소를 지원하는 인터넷 프로토콜입니다(이전에 32비트 주소 체계를 지원하는 IPv4를 개선한 새 버전). 네트워크 인터페이스에서 IPv6를 활성화시켜야 합니다. 자세한 내용은 데이터를 호스팅하는 운영 체제의 도움말을 참조하십시오.

호스팅 시스템이 IPv6을 지원하면 다음과 같이 대괄호([])로 묶은 URL에 IPv6 리터럴 주소를 지정할 수 있습니다.

[2001:db8:ccc3:ffff:0:444d:555e:666f]

Flash Player에서는 다음 규칙에 따라 리터럴 IPv6 값을 반환합니다.

  • Flash Player에서는 IPv6 주소에 대해 긴 형식의 문자열을 반환합니다.

  • IP 값에는 콜론이 두 개인 약어가 없습니다.

  • 16진수는 소문자로만 사용됩니다.

  • IPv6 주소는 대괄호([])로 묶습니다.

  • 각 주소는 0~4개의 16진수로 출력됩니다. 이때 선행 0은 생략됩니다.

  • 다음 예외를 제외하고 모든 0의 주소는 이중 콜론이 아닌 단일 0으로 출력됩니다.

Flash Player에서 반환되는 IPv6 값에는 다음과 같은 예외가 있습니다.

  • 지정되지 않은 IPv6 주소(모든 0)는 [::]으로 출력됩니다.

  • 루프백 또는 로컬 호스트 IPv6 주소는 [::1]로 출력됩니다.

  • IPv4 매핑 주소(IPv6으로 변환된 주소)는 [::ffff:a.b.c.d]로 출력됩니다. 여기서 a.b.c.d는 점으로 구분된 일반적인 IPv4 값입니다.

  • IPv4 호환 주소는 [::a.b.c.d]로 출력됩니다. 여기서 a.b.c.d는 점으로 구분된 일반적인 IPv4 값입니다.