//--------------------------------------------------------------
// telnet 프로그램 Telnet.java
//
// 이 프로그램은 설정된 주소의 포트에 표준 입/출력으로 접속한다.
// 접속 포트가 23번인 경우, 협상을 행한다.
//
// 사용법(1) : java Telnet 서버주소 포트번호
// 사용법(2) : java Telnet 서버주소
// (2)의 경우 포트 번호는 23을 가정한다.
// 사용예 : java Telnet netlab.woosong.ac.kr
// 종료시는 CTRL+C를 누른다.
//-------------------------------------------------------------
// 라이브러리 이용
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
// Telnet 클래스
// Telnet 클래스는 네트워크 접속을 관리한다.
// StreamConnector 클래스를 사용하여 slot 처리를 행한다.
// Constructor는 2 종류가 있고 사용법은 각각 (1)(2)에 대응한다.
public class Telnet {
Socket serverSocket; // 접속용 소켓
public OutputStream serverOutput; // 네트워크 출력용 스트림
public BufferedInputStream serverInput; // 네트워크 입력용 스트림
String host; // 접속 서버의 주소
int port; // 접속 서버의 포트 번호
static final int DEFAULT_TELNET_PORT = 23; // telnet의 포트 번호(23)
// Constructor(1) 주소와 포트 번호가 지정된 경우
public Telnet(String host, int port){
this.host = host;
this.port = port;
}
// Constructor(2) 주소만 지정된 경우
public Telnet(String host){
this(host, DEFAULT_TELNET_PORT); // telnet 포트를 설정
} // openConnection 메소드
// 주소와 포트 번호로부터 소켓을 만들고 스트림을 작성한다.
public void openConnection() throws IOException,UnknownHostException {
serverSocket = new Socket(host, port);
serverOutput = serverSocket.getOutputStream();
serverInput = new BufferedInputStream(serverSocket.getInputStream());
// 접속 상대방이 telnet 포트번호이므로 협상을 행한다.
if (port == DEFAULT_TELNET_PORT){
negotiation(serverInput, serverOutput);
}
}
// main_proc 메소드
// 네트워크와의 통신을 행하는 슬롯을 시작시킨다.
public void main_proc() throws IOException {
try { // 슬롯용 클래스 StreamConnector의 객체를 생성한다.
StreamConnector stdin_to_socket = new StreamConnector(System.in, serverOutput);
StreamConnector socket_to_stdout = new StreamConnector(serverInput, System.out); // 슬롯을 생성한다.
Thread input_thread = new Thread(stdin_to_socket);
Thread output_thread = new Thread(socket_to_stdout); // 슬롯을 시작한다.
input_thread.start();
output_thread.start();
} catch(Exception e){
System.err.print(e);
System.exit(1);
}
}
// 협상에 사용하는 코맨드의 정의
static final byte IAC = (byte) 255;
static final byte DONT = (byte) 254;
static final byte DO = (byte) 253;
static final byte WONT = (byte) 252;
static final byte WILL = (byte) 251;
// negotiation 메소드
// NVT에 의한 통신을 협상한다.
static void negotiation(BufferedInputStream in,OutputStream out) throws IOException {
byte[] buff = new byte[3]; // 코맨드 수신용 배열
while(true) {
in.mark(buff.length);
if (in.available() >= buff.length) {
in.read(buff);
if (buff[0] != IAC){// 협상 종료
in.reset();
return;
} else if (buff[1] == DO) { //DO 코맨드에 대해서는
buff[1] = WONT; // WON'T는 반환한다.
out.write(buff);
}
}
}
}
// main 메소드
// TCP 연결을 열어서 처리를 개시한다.
public static void main(String[] arg){
try {
Telnet t = null; // 인수의 개수에 의해 constructor가 달라진다.
switch (arg.length){
case 1: // 서버 주소만을 정의
t = new Telnet(arg[0]); break;
case 2: // 주소와 포트를 확정
t = new Telnet(arg[0], Integer.parseInt(arg[1])); break;
default: // 사용법이 다른 경우
System.out.println("usage: java Telnet <host name> {<port number>}"); return;
}
System.out.println("===================================");
t.openConnection();
System.out.println("===================================");
t.main_proc();
System.out.println("===================================");
}catch(Exception e){
e.printStackTrace();
System.exit(1);
}
}
}
// StreamConnector 클래스
// 스트림을 받아서 처리한 후 양자를 통합하여 데이터를 받아서 넘겨준다.
// StreamConnector 클래스는 슬롯을 구성하기 위한 클래스이다.
class StreamConnector implements Runnable {
InputStream src = null;
OutputStream dist = null;// Constructor 입출력 스트림을 받아서 처리한다.
public StreamConnector(InputStream in, OutputStream out){
src = in;
dist = out;
}
// 처리 부분
// 스트림 읽고 쓰기를 무한히 반복한다.
public void run(){
byte[] buff = new byte[1024];
while (true) {
try {
int n = src.read(buff);
if (n > 0)
dist.write(buff, 0, n);
} catch(Exception e){
e.printStackTrace();
System.err.print(e);
System.exit(1);
}
}
}
}
'Java' 카테고리의 다른 글
[JAVA] http로 연결하여 결과값 가져오기 (0) | 2010.10.12 |
---|---|
[JAVA] 네트워킹 - 서브넷 마스크 계산하기 (정수로 변경프로그램) (0) | 2010.09.10 |
[JAVA] window에서 명령어(command)날리기 (0) | 2010.08.12 |
자바 정규식(java.util.regex.Pattern) (0) | 2010.06.14 |
JNI 만들기 (0) | 2010.05.17 |