Whiteship's Note


All About Sockets 2

Java : 2007.09.26 15:07


Reading from and Writing to a Socket

import java.io.*;
import java.net.*;

public class EchoClient {
    public static void main(String[] args) throws IOException {

        Socket echoSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;

        try {
            echoSocket = new Socket("taranis", 7);
            out = new PrintWriter(echoSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(
                                        echoSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: taranis.");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for "
                               + "the connection to: taranis.");
            System.exit(1);
        }

    BufferedReader stdIn = new BufferedReader(
                                   new InputStreamReader(System.in));
    String userInput;

    while ((userInput = stdIn.readLine()) != null) {
        out.println(userInput);
        System.out.println("echo: " + in.readLine());
    }

    out.close();
    in.close();
    stdIn.close();
    echoSocket.close();
    }
}

클라이언트 쪽에서 Socket을 사용하는 방법은 매우 간단합니다.
먼저 Socket 객체를 만들기 위해서 생성자에 서버의 IP 와 포트넘버를 생성자에 넘겨줍니다.
그리고 서버에 어떤 메시지를 보내기 위해서는 PrintWriter를 사용하고, 서버로 부터 데이터를 받아 오기 위해서는 BufferedReader를 사용하면 됩니다. 물론 두 객체는 모두 Socket을 사용하여 생성합니다.
마지막으로 열려있는 자원들을 close 해줌으로써 메모리 누수를 방지합니다.

클라이언트 프로그램 구현 절차는 다음과 같습니다.
   1. Open a socket.
   2. Open an input stream and output stream to the socket.
   3. Read from and write to the stream according to the server's protocol.
   4. Close the streams.
   5. Close the socket.

Writing the Server Side of a Socket
import java.net.*;
import java.io.*;

public class KnockKnockServer {
public static void main(String[] args) throws IOException {

ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}

Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}

PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
String inputLine, outputLine;
KnockKnockProtocol kkp = new KnockKnockProtocol();

outputLine = kkp.processInput(null);
out.println(outputLine);

while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye."))
break;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
위의 코드에서 주목해야 할 부분에 빨간색으로 표시해 두었습니다.
ServerSocket를 생성하여 클라이언트의 접속을 받아들일 준비를 합니다. 이 때 클라이언트의 요청을 받을 포트 번호를 생성자에 넘겨줍니다.
그런 다음 클라이언트에서 요청이 오면(serverSocket.accept()) 새로운 Socket 객체를 만들고, 그 Socket과 클라이언트 간에 의사소통을 위한 PrintWriter와 BufferedReader 객체를 생성합니다.
그리고 나서 서버에서는 클라이언트로 부터 BufferedReader 객체를 사용하여 데이터를 읽어오고, 읽어온 데이터를 처리하고, 마지마긍로 PrintWriter를 사용하여 다시 클라이언트에게 결과를 보내줍니다.

KnockKnockClient

여기까지는 매우 간단합니다.

만약에 위와 같은 상황에서 클라이언트 100가 하나의 서버에 접속하게 되면 어떻게 될까요? 100번째 클라이언트는 앞에 있는 99개의 클라이언트와 서버의 접속이 끝날 때까지 기다려야 합니다. 이럴 때 쯤 등장하는 녀석이 바로 멀티쓰레드.

위의 서버 클래스는 클라이언트의 접속을 받은 다음 새로운 소켓을 만들어서 Thread로 넘겨주는 일만 하고, 실제 클라이언트와 열심히 읽고 쓰는 일은 Thread가 알아서 하도록 하면 100번째 클라이언트가 기다리는 시간은 오직 자신을 위해 일해 줄 서버의 소켓을 생성하는 시간밖에 되지 않을 겁니다.

KKMultiServer, KKMultiServerThread

2007/09/26 - [Java] - All About Sockets 1

'Java' 카테고리의 다른 글

File.delete() 메소드의 리턴값이 false일 경우.  (4) 2008.03.07
JNDI 관련 글  (2) 2007.11.01
Java 6에서 @Override  (4) 2007.10.01
쓰레드를 공부하는 학생과의 대화  (1) 2007.09.29
Concurrent Programming with J2SE 5.0  (2) 2007.09.29
All About Sockets 2  (0) 2007.09.26
All About Sockets 1  (0) 2007.09.26
Java에서 URL 다루기 2  (2) 2007.09.26
Java에서 URL 다루기 1  (0) 2007.09.18
자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
Autoboxing의 오묘함  (2) 2007.09.09
top

Write a comment.


All About Sockets 1

Java : 2007.09.26 13:49


참조 : http://java.sun.com/docs/books/tutorial/networking/sockets/index.html

앞에서 살펴보았던 URL과 URLConnection 객체를 사용한 프로그래밍은 상당히 높은 추상화 단계에서 접근하는 것입니다. 하지만 만약 클라이언트-서버 프로그래밍을 하게 된다면, 매우 구체적은 단계에서 접근할 필요가 있습니다.

클라이언트-서버 프로그램들은 각자 소켓을 사용하여 서로를 연결하고 있으며 자신이 가지고 있는 소켓을 통해서 읽기 쓰기 작업을 합니다.

What Is a Socket?

네트워크에서 동작 중이 두 개의 애플리케이션을 잇는 Endpoint로 포트 번호를 사용하여 TCP 계층에서 보내진 데이터가 어떤 애플리케이션을 위한 것인지 식별할 수 있도록 합니다.

서버쪽에서는 클라이언트가 접속할 Endpoint로 특정 포트 번호를 사용하여 Socket을 생성합니다.
사용자 삽입 이미지
그리고 해당 Socket으로 접속이 오면 새로운 Socket을 만들어서 접근해온 Client의 IP와 포트 번호를 설정합니다. 왜냐면, 다른 클라이언트의 접속들도 동일한 Socket으로 받아들이기 위해서입니다.
사용자 삽입 이미지
즉, 모든 접속은 한 Socket에서 받아 들이고, 새로운 접속이 올 때마다 Server쪽에 새로운 Socket을 생성하여 그 Socket과 클라이언트의 Socket이 의사소통을 하게 됩니다.

자바에서 Socket을 위해 제공하는 API로 Socket와 SeverSocket이 있습니다. ServetSocket이 위에서 언급한 접속을 받아 들이기 위한(listerner) Socket을 위한 구현체이고, Socket은 그 이외의 모든 Socket을 위한 구현체 입니다.

2007/09/26 - [Java] - Java에서 URL 다루기 2
2007/09/18 - [Java] - Java에서 URL 다루기 1


'Java' 카테고리의 다른 글

JNDI 관련 글  (2) 2007.11.01
Java 6에서 @Override  (4) 2007.10.01
쓰레드를 공부하는 학생과의 대화  (1) 2007.09.29
Concurrent Programming with J2SE 5.0  (2) 2007.09.29
All About Sockets 2  (0) 2007.09.26
All About Sockets 1  (0) 2007.09.26
Java에서 URL 다루기 2  (2) 2007.09.26
Java에서 URL 다루기 1  (0) 2007.09.18
자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
Autoboxing의 오묘함  (2) 2007.09.09
객체 크기 구하기  (2) 2007.08.14
top

Write a comment.


Java에서 URL 다루기 2

Java : 2007.09.26 12:37


Connecting to a URL

URL 객체를 생성한 다음 openConnection 메소드를 사용하여 URLConnection 객체를 생성할 수 있습니다. 다음은 Yahoo.com URL의 Connection 객체를 만드는 예제 코드입니다.

try {
    URL yahoo = new URL("http://www.yahoo.com/");
    URLConnection yahooConnection = yahoo.openConnection();
    yahooConnection.connect();

} catch (MalformedURLException e) {     // new URL() failed
    . . .
} catch (IOException e) {               // openConnection() failed
    . . .
}

URLConnection.connect 메소드를 사용하여 Connection을 초기화 할 수 있는데 매번 명시적으로 호출하지 않아도 됩니다. getInputStream, getOutputStream 같은 메소드를 호출할 때 암묵적으로 호출하기 때문입니다.

Reading from and Writing to a URLConnection

URLConnection 클래스는 네트워크를 사용하여 URL과 의사소통을 하기 위한 다양한 메소드를 제공합니다. HTTP를 위한 기능들이 많이 있지만, 대부분의 다른 프로토콜을 위한 기능도 제공하고 있습니다.

Reading from a URLConnection

URL에서 직접 읽어오기와 비슷합니다.

import java.net.*;
import java.io.*;

public class URLConnectionReader {
    public static void main(String[] args) throws Exception {
        URL yahoo = new URL("http://www.yahoo.com/");
        URLConnection yc = yahoo.openConnection();
        BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                yc.getInputStream()));
        String inputLine;

        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
        in.close();
    }
}

Writing to a URLConnection

URLConnection 객체를 사용하여 OutputStream 객체를 얻어서 ObjectOutputStream을 생성한 다음 URL로 원하는 데이터를 posting 한 뒤에 서버에서 처리한 결과를 URLConnection객체의 InputStream을 받아서 BufferedReader로 읽는 프로그램입니다.
import java.io.*;
import java.net.*;

public class Reverse {
public static void main(String[] args) throws Exception {

if (args.length != 2) {
System.err.println("Usage: java Reverse " +
"http://<location of your servlet/script>" +
" string_to_reverse");
System.exit(1);
}

String stringToReverse = URLEncoder.encode(args[1], "UTF-8");

URL url = new URL(args[0]);
URLConnection connection = url.openConnection();
connection.setDoOutput(true);

OutputStreamWriter out = new OutputStreamWriter(
connection.getOutputStream());
out.write("string=" + stringToReverse);
out.close();

BufferedReader in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));

String decodedString;

while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
}
}
2007/09/18 - [Java] - Java에서 URL 다루기 1

top

  1. Favicon of https://wannastopa.tistory.com BlogIcon 류재섭 2009.05.11 02:06 신고 PERM. MOD/DEL REPLY

    잘 봤습니다.

    퍼갈께요~~

    좋은 자료 감사합니다. ~~

    Favicon of http://whiteship.me BlogIcon 기선 2009.05.11 07:55 PERM MOD/DEL

Write a comment.