안녕, 세상!

11. 네트워크 프로그래밍 본문

It공부/Java

11. 네트워크 프로그래밍

dev_Lumin 2020. 7. 18. 15:57

(1) 인터넷의 구성 요소

TCP/IP 프로토콜

인터넷은 컴퓨터 간 정보를 교환할 수 있는 기능이 있는 컴퓨터 통신망입니다.

따라서 컴퓨터와 통신 노드 간에 정보를 교환하기 위한 프로토콜이 필요하며, 인터넷에서는 TCP(Transmission Control Protoc

ol) / IP(Internet Protocol)를 인터넷의 표준 프로토콜로 개발하여 사용하고 있습니다.

 

TCP/IP는 응용 계층, 전송계층, 인터넷 계층, 물리 계층 등 4개의 계층 구조를 갖습니다.

 

 

① 응용 계층(Application Layer) 

 실제로 네트워크를 사용하는 FTP, Telnet, SMTP 등의 응용프로그램으로 이루어져 있습니다.

 

 

② 전송 계층(Transport Layer)

목표 시스템까지 데이터를 전송하는 역할을 하며 시스템의 주소와 포트를 이용해서 통신합니다.

전송계층은 TCP와 UDP 두 가지가 있고, TCP는 연결형(Connect-Oriented)으로 스트림 형태의 데이터를 에러 없이 전송하도록 지원하고, UDP비연결형(Connectionless) 으로 데이터그램(Datagram)을 전송합니다.

 

TCP는 데이터를 중복과 에러 없이 순서대로 보내기 위해 몇 가지 헤더가 필요하고 시스템 간의 연결을 계속 유지해야 합니다.

UDP는 네트워크에서 최소의 부담으로 데이터를 전송하는데 이용되며, 패킷이 전송되지 않거나 중복되어 전송될 수 있기 때문에 안정성이 떨어집니다.

 

 

③ 인터넷 계층(Internet Layer)

인터넷 계층은 IP 프로토콜에서 다루는 패킷인 데이터그램(Datagram)을 정의하고 데이터그램의 경로를 설정하는 역할을 합니다.

데이터그램은 보낸 주소, 받을 주소, 보내는 데이터와 몇 가지 조절 필드를 가집니다.

인터넷 계층에서는 데이터그램이 가지고 있는 주소를 판독하여 네트워크에서 주소를 찾아가서 해당 호스트가 데이터그램을 받을 수 있도록 전송합니다.

 

 

④ 네트워크 접속 계층(Network Access Layer)

네트워크 접속 계층은 운영체제의 네트워크 카드와 디바이스 드라이버 등과 같은 하드웨어적인 요소와 관련된 것을 지원하는 계층입니다. 

 

 

 

 

 

(2) IP 주소 (IP Address)

TCP/IP 프로토콜로 네트워크가 구축되어 있다면 네트워크에 속해 있는 각 컴퓨터는 자신을 나타내는 주소를 가지고 있어야 합니다.

각 컴퓨터는 주소를 하나만 가지고 있어야 합니다.

TCP/IP 에서 IP의 역할은 데이터를 전송하는 것인데, 데이터를 전송하기 위해 수신처의 주소를 알아야 하며 주소는 네트워크 상에서 유일해야 합니다.

데이터 전송을 위해 필요한 주소를 IP주소라고 하고 각 통신장비 및 컴퓨터에 대해서 유일한 값으로 할당됩니다.

IP주소는 네트워크를 나타내는 네트워크 정보와 네트워크 내에서 특정 컴퓨터를 가리키도록 하는 호스트 정보로 구성됩니다.

 

① IPv4(Internet Protocol ver 4)

Ipv4 주소는 32비트로 구성되고 총 십지수 12자리로 나타내며 네 부분으로 나누어집니다.

 

A 클래스 : 최고위의 class로 1.0.0.0 ~ 126.255.255.255 범위의 IP 주소를 가지고 2,3,4 번째 단위의 세 숫자는 A Class가 자유롭게 네트워크 사용자에게 부여할 수 있습니다.

 

B 클래스 : 두 번째로 높은 단위의 Class로 128.0.0.0 ~ 191.255.255.255 범위의 IP 주소를 자기며, 두 번째 단위의 세 숫자는 B Class가 접속할 수 있는 네트워크를 지시합니다.

 

C 클래스 : 최하위의 Class로 192.0.0.0 ~ 223.255.255.255 범위의 IP 주소를 가지며, 두 번째와 세 번째 단위의 세 숫자는 C Class가 접속할 수 있는 네트워크를 지시합니다.

 

D 클래스( 224.0.0.0 ~ 239.255.255.255 ) 와 E 클래스( 240.0.0.0 ~ 255.255.255.255 ) 는 다른 용도로 사용할 목적으로 남겨 두고 있습니다.

 

 

 

② IPv6

인터넷 사용자가 급증하여 IP 주소가 부족할 수 있기에 그 대안으로 준비한것입니다.

주소길이가 128비트로 확장되었으며, 수 많은 기기에 IP 주소를 부여할 수 있을 만큼 충분합니다.

또한 사용자 인증과 보안기능을 지원하므로 IPv4에 비해 훨씬 안정적인 네트워크를 구성할 수 있습니다.

IPv6주소는 32자리의 16진수를 4자리씩 끊어서 표현합니다.

 

 

 

(3) 소켓(Socket) 프로그래밍

소켓은 서버 측에 있는 프로그램과 클라이언트 측에 있는 두 개의 프로그램이 특정 포트를 통해 연결되어 양방향 통신이 가능하도록 합니다.

서버와 클라이언트 간에 형성된 채널을 통해 클라이언트가 서비스를 요청(Request) 하면 서버는 그 요청의 내용을 듣게(Listen)되며, 해당 서비스 프로그램을 수행하여 그 결과를 연결되어 있는 채널로 돌려줍니다.
서버와 클라이언트 간의 통신 과정을 보여주는 흐름도는 다음과 같습니다.

 

 

자바에서 java.net 패키지에서 서버를 위한 ServerSocket 클래스클라이언트를 위한 Socket 클래스를 제공하고 있습니다.

 

 

① ServerSocket 클래스

클라이언트와 통신하기 위해서 서버 측에 생성하는 소켓이고 네트워크 상에서 사전에 설정된 포트를 통하여 자신에게 오는 요청을 계속 기다리다가 요청이 입력되면 요청에 맞는 서비스를 수행하여 결과를 돌려 줍니다.

ServerSocket 클래스의 생성자는 다음과 같습니다.

 

 

ServerSocket(int port)

ServerSocket(int port, int backlog)

ServerSocket(int port, int backlog, InetAddress bindaddr)

 

 

다음은 ServerSocket 클래스가 제공하는 주요 메소드입니다.

메소드 설명
Socket accept() 서버 소켓에 대한 연결을 받아들임
void close() 서버 소켓을 닫음
InetAdress getInetAddress()  서버 소켓의 로컬 주소를 얻음
int getLocalPort() 서버 소켓에 연결된 포트 번호를 얻음

 

 

 

② Socket 클래스

서버와의 연결을 위해 클라이언트 측에 생성하는 소켓은 Socket 클래스에서 제공합니다.

무조건 클리이언트 소켓만을 지칭하는 클래스 역할을 하는 것이 아니라 소켓 자체를 가리키는 역할도 합니다.

다음은 Socket 클래스의 생성자입니다.

 

 

Socket(InetAddress address, int port)

Socket(InetAddress host, int port, boolean stream)

Socket(InetAddress address, int port, InetAddress localAddr, int localPort)

Socket(String host, int port)

Socket(String host, int port, boolean stream)

Socket(String host, int port, InetAddress localAddr, int localPort)

 

 

Socket 클래스가 제공하는 주요 메소드입니다.

메소드 설명
void close() 소켓을 닫음
InetAddress getInetAddress() 소켓이 연결되어 있는 원격 IP주소를 얻음
InputStream getInputStream() 소켓에 대한 입력 스트림을 얻음
InetAddress getLocalAddress() 소켓이 갖는 지역 IP 주소를 얻음
int getLocalPort() 소켓이 갖는 지역 포트 번호를 얻음
OutputStreamgetOutputStream() 소켓에 대한 출력 스트림을 얻음
int getPort() 소켓에 연결되어 있는 원격 포트 번호를 얻음

 

소켓 프로그램이 정상적으로 작동하기 위해서는 서버 측과 클라이언트 측에 모두 소켓이 설치되어 있어야 합니다.

서버 측에 있는 특정한 포트를 이용할 경우는 서버 측 소켓은 이미 설치가 되어 있는 것이기 때문에 클라이언트 측에만 소켓을 설치하여도 프로그램을 작동할 수 있습니다.

 

 

다음은 ServerSocket 클래스와 Socket 클래스를 이용한 소켓 통신 예입니다.

SocketServer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.*;
import java.net.*;   // 네트워크 관련 클래스 사용을 위해서
public class SocketServer {
    public static void main(String[] args) {
        ServerSocket ss;
        Socket sc;
        BufferedReader in;   // input쪽 필터 스트림
        PrintWriter out;    // output쪽 필터 스트림
        
        try {
            ss=new ServerSocket(1111);   // 1111포트를 사용하는 서버 소켓을 생성
            sc=ss.accept();    // 클라이언트의 접속을 기다리며 접속이 되면 소켓을 만들고 sc변수가 참조하도록 대입
            while(true)
            {
                in = new BufferedReader(new InputStreamReader(sc.getInputStream()));
                // 클라이언트로부터 데이터를 읽기위한 입력 스트림
                out = new PrintWriter(sc.getOutputStream(),true);
                // 클라이언트로의 출력 스트림
                String inLine = in.readLine();  // 클라이언트로부터 데이터 읽기
                if(inLine == null)         // 더이상 값 없으면 break
                    break;
                System.out.println("서버수신:"+inLine);  // 받은 값 출력
                out.println(inLine+" 반사다!");      // 클라이언트로 값 보내기
                System.out.println("서버송신:"+inLine+" 반사다!");  //  보낸 값 출력
                
            }
        }catch(IOException ex) {
            ex.printStackTrace();
        }
    }
}
cs

 

SocketClient

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.io.*;
import java.net.*;
public class SocketClient {
    public static void main(String [] args) {
        Socket sc;
        BufferedReader in, stdin;
        PrintWriter out;
        String inLine = null;
        String host = "localhost";
        try {
            sc= new Socket(host,1111);  // 서버의 '1111'포트로 소켓을 연결. sc는 클라이언트의 소켓이지만 서버의 소켓을 가르킴
                                        // 서버의 주소가 'localhost'로 동일한 컴퓨터라서 
            out = new PrintWriter(sc.getOutputStream(),true);
            // 서버로의 출력 스트림을 얻음
            in = new BufferedReader(new InputStreamReader(sc.getInputStream()));
            // 클라이언트로의 입력 스트림을 얻음 (서버로부터 데이터를 얻음)
            stdin=new BufferedReader(new InputStreamReader(System.in));
            System.out.print("클라이언트송신: ");
            while((inLine = stdin.readLine())!=null) {
                // 키보드로 부터 서버로 송신할 데이터를입력함. 사용자가 데이터의 끝을 나타내는 ctrl+z 를 입력하면
                // readLine()은 null을 반한함
                out.println(inLine);  // 사용자가 입력한 데이터를 서버로 송신
                System.out.println("클라이언트수신: "+in.readLine());
                System.out.print("클라이언트송신: ");
            }
            in.close();    
            out.close();
            sc.close();   // 입출력 스트림과 소켓 닫음
        }catch(IOException ex) {
            ex.printStackTrace();
        }
    }
cs

 

 

우선 위와 같이 실행하려면 콘솔을 두 개 만들어야 합니다.

 

기존에 Eclipse에 콘솔이 없다면 [window] -> [Show View] -> [console] 을 누르면 콘솔이 하나 생깁니다.

콘솔을 하나 더 추가 시키고 싶으면 기존의 콘솔에

다음과 같이 New Console View 를 클릭하면 콘솔이 하나 더 생깁니다.

 

위의 코드는 SocketServer을 먼저 Run 해주고 바로 이어서 SocketClient를 Run 해줘야 합니다.

두 개의 콘솔에 각각 어떤 코드의 콘솔인지 설정은 다음과 같이

두 코드를 모두 Run을 해주면 위의 아이콘에 색깔이 들어오며 아래 화살표를 눌러서 각각 코드를 선택 가능합니다.

한쪽 콘솔에는 SocketServer을 선택해주시고 나머지 콘솔에는 SocketClient 코드를 선택해주면 위의 결과처럼 잘 확인할 수 있습니다.

 

 

 

 

 

(4) UDP프로그래밍

UDP 프로토콜은 데이터그램이라는 데이터 패킷을 사용합니다.

데이터그램 패킷들은 서로 내용이 독립적이며 패킷 내에 목적지에 대한 정보를 가지고 송신자로부터 수신자로 전송됩니다.

UDP는 메시지가 제대로 도착했는지 확인하는 응답을 사용하지 않고 수신된 메시지의 순서를 마추지 않으며 정보 흐름 속도를 제어하기 위한 피드백을 제공하지 않기 때문에, UDP 메시지는 손실되거나, 중복되거나, 비순서적으로 도착할 수 있습니다.

 

UDP 프로그래밍에서는 서버 소켓이 별도로 존재하지 않으며, 클라이언트 소켓에 해당하는 DatagramSocket 개체만이 존재합니다.

UDP프로그래밍은 비연결형이므로 서버와 클라이언트의 접속을 담당할 서버 소켓이 필요없기 때문입니다.

 

자바언어에서 'java.net' 패키지에서 데이터그램 패킷을 생성하고 제어하기 위한 DatagramPacket 클래스와 데이터그램 패킷을 보내거나 받기 위한 데이터그램 소켓 기능을 제공해주는 DatagramSocket 클래스르 제공합니다.

 

데이터그램 패킷은 비연결 패킷 전송 서비스를 구현하기 위해 사용됩니다.

메시지는 패킷 내에 포함되어 있는 정보를 바탕으로 하나의 호스트에서 다른 호스트로 전송됩니다.

전송된 여러 개의 패킷은 서로 다르게 전송 경로가 설정될 것이며, 원래의 순서와 관계없이 도착할 수 있습니다.
DatagramPacket 클래스의 생성자는 다음과 같습니다.

 

 

DatagramPacket(byte[] buf, int length)

DatagramPacket(byte[] buf, int offset, int length)

DatagramPacket(byte[] buf, int length, InetAddress address, int port)

 

 

DataGramPacket 클래스가 제공하는 주요 메소드는 다음과 같습니다.

메소드 설명
InetAddress getAddress() 송수신 호스트의 IP주소를 얻음
byte[] getData() 데이터를 얻음
int getLength 데이터의 크기를 얻음
int getOffset() 데이터의 offset을 얻음
int getPort() 원격 호스트의 포트번호를 얻음
void setAddress(InetAddres iaddr) IP주소를 설정함
void setData(byte[] buf)
void setData(byte[] buf, int offset, int length)
데이터를 설정함
void setLength(int length) 패킷 크기를 설정함
void setPort(int port) 포트 번호를 설정함

 

 

DataGramSocket 클래스

DatagramSocket 클래스는 데이터그램 패킷을 보내거나 받기 위한 데이터그램 소켓 기능을 제공해주는 클래스로, 패킷의 송수신 서비스를 위한 포트입니다.

데이터그램 소켓에서 보내지거나 데이터 그램 소켓이 받아들인 각각의 패킷은 개별적으로 경로를 설정하여 보내집니다.

메소드 설명
void close() 소켓을 닫음
void connect(InetAddress address, int port) 원격 소켓에 연결함
void disconnect() 연결을 해제함
InetAddress getInetAddress() 소켓이 연결되어 있는 IP주소를 얻음
InetAddress getLocalAddress() 소켓이 연결된 로컬 IP주소를 얻음
int getLocalPort() 소켓에 연결된 로컬포트를 얻음
int getPort() 소켓이 연결되어 있는 원격 포트를 얻음
void receive(DatagramPacket p) 데이트그램 패킷을 받음
void send(DatagramPacket p) 데이터그램 패킷을 송신함

 

 

다음은 udp로 클라이언트와 서버 송수신 하는 예제입니다.

DatagramServer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.io.*;
import java.net.*;
public class datagramserver {
    public static void main(String [] args) {
        DatagramPacket packet = null;
        byte[] b= new byte[256];
        try {
            DatagramSocket socket = new DatagramSocket(1111); //1111포트로 데이터그램 소켓을 생성
            while(true) {           //클라이언트로부터 오는 요청 내용을 저장할 입력 데이터그램 패킷을 생성
                packet = new DatagramPacket(b, b.length); 
                socket.receive(packet);  // receive를 호출하여 클라이언트로부터 패킷을 수신
                String received= new String(packet.getData()); //클라이언트로부터 받은 패킷을 received 문자열에 넣음
                InetAddress address = packet.getAddress(); // 패킷을 송신한 클라이언트의 주소와
                int port = packet.getPort();               // 포트를 얻음
                b= received.getBytes();             // 클라이언트로부터 수신한 데이터를 바이트배열에 저장하고 
                packet = new DatagramPacket(b,b.length,address,port); // 얻은 값을 매개변수로하여 패킷을 생성하고
                socket.send(packet);                              // send 메소드를 호출하여 다시 클라이언트에게 송신
            }
        }catch(IOException ex) {
            ex.printStackTrace();
        }
    }
cs

 

DatagramClient

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.io.*;
import java.net.*;
public class datagramclient {
    public static void main(String[] args) {
        byte[] b= new byte[256];
        String host= "localhost";
        String send =null;
        DatagramPacket packet = null;
        BufferedReader in;
        try {
            DatagramSocket socket = new DatagramSocket(); // 데이터그램 소켓 생성
            InetAddress address = InetAddress.getByName(host); 
            // 서버의 주소를 얻음, 서버가 'localhost'이므로 동일한 컴퓨터를 서버와 클라이언트로 사용함
            in = new BufferedReader(new InputStreamReader(System.in));  // 입력스트림
            System.out.print("클라이언트송신: ");
            while((send=in.readLine())!=null) {  //서버로 송신할 데이터 입력
                b=send.getBytes();
                packet = new DatagramPacket(b,b.length, address,1111); 
                //사용자가 입력한 문자열을 바이트배열로 변환하여 포트 '1111'을 통하여 
                socket.send(packet);  // 서버로 송신
                packet = new DatagramPacket(b, b.length); // 서버로부터 오는 응답 내용을 저장할 입력 데이터그램 패킷 생성
                socket.receive(packet);   // 서버로 부터 수신
                String received = new String(packet.getData()); // 받은 데이터 문자열로 전환
                System.out.println("클라이언트수신: "+received);// 출력
                System.out.print("클라이언트송신: ");
            }
            socket.close();
        }catch(IOException ex) {
            ex.printStackTrace();
        }
    }
}
cs

 

 

 

 

(5) InetAddress 클래스

InetAddress 클래스가 제공하는 주요 메소드는 다음과 같습니다.

메소드 설명
byte[] getAddress() InetAddress 객체가 가지고 있는 IP주소의 바이트 배열을 반환합니다.
String getHostAddress() IP 주소 정보를 나타내는 문자열을 반환합니다.
String getHostName() 객체가 가지는 호스트 이름을 문자열로 반환합니다.
static InetAddress[] getAllByName(String host) 주어진 이름을 갖는 호스트(컴퓨터)에 다중 IP가 할당되어 있는 경우, 할당된 모든 IP 주소를 반환합니다.
static InetAddress getByName(String host) 주어진 이름을 갖는 호스트(컴퓨터)의 IP 주솔르 반환합니다.
InetAddress getLocalHost() 현재 컴퓨터를 나타내는 InetAddress 객체를 반환합니다.

 

 

 

 

(6) URL 클래스

URL 클래스는 웹 상에 존재하는 자원에 접근하기 위해 필요한 자원의 주소를 나타내기 위한 기능을 제공합니다.

즉, 자바에서 URL을 사용할 수 있는 기능을 제공해 줍니다.

자원은 파일이나 디렉토리와 같이 단순한 것일 수도 있고, 데이터베이스와 같은 복잡한 객체의 참조일 수도 있습니다.

 

 

URL은 다음과 같이 부분으로 나눌 수 있습니다.

 

프로토콜(Protocol) : 자원에 접근하기 위해 사용되는 프로토콜. http, ftp, file 등

 

호스트(Host) : 접근하려는 자원이 저장되어 있는 컴퓨터의 이름.  www.daum.net  등

 

포트(port) : URL은 원격 호스트 상에서 생성된 TCP 연결에 대한 포트 번호를 지정할 수 있음

포트 번호가 생략되어 있는 경우에는 각 프로토콜에 따라 디폴트 값을 사용함 (http는 80)

 

경로명(Path) : 접근하려는 자원이 저장되어 있는 호스트 상의 경로.

 

앵커(Anchor) : URL에서는 참조(reference)를 나타낼 수 있는데 이를 앵커라고 함. 문자 '#'으로 나타냄

 

 

 

URL 클래스는 다음과 같은 생성자를 사용하여 객체를 생성할 수 있습니다.

 

 

URL(String spec) 

URL(String protocol, String host, int port, String file)

URL(String protocol, String host, int port, String file, URLStreamHandler handler)

URL(String protocol, String host, String file)

URL(URL context, String spec)

URL(URL context, String spec, URLStreamHandler handler)

 

 

URL 클래스가 제공하는 주요 메소드는 다음과 같습니다.

메소드 설명
Object getContent() URL의 컨텐츠를 반환
String getFile() URL의 파일명을 반환
String getHost() URL의 호스트 이름을 반환
String getPath() URL의 경로를 반환
int getPort() URL의 포트 번호를 반환
String getProtocol() URL의 프로토콜 이름을 반환
String getRef() URL의 앵커를 반환
URLConnection openConnection() URL이 참조하는 원격 객체의 접속을 나타내는 URLConnection 객체를 반환
InputStream openStream() URL에 접속을 오픈해 그 접속으로부터 입력하기 위한 inputStream을 반환
boolean sameFile(URL other) 2개의 URL이 같은지 비교
String toExternalForm() URL에 대한 문자열 객체를 생성
String toString() URL에 대한 문자열 객체를 생성
URL toURI() URL에 해당하는 URL를 반환

 

 

다음은 간단한 예제입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.io.*;   // 입출력 관련 클래스 사용하기 위해서
import java.net.*;  // 네트워크 관련된 클래스 사용하기 위해서
 
public class urlsample {
    public static void main(String args[]) throws Exception {
        URL url=new URL("http://www.google.co.kr/"); //해당 주소에 해당하는 URL 객체 생성
        System.out.println(url.getHost() + "의 내용: \n");
        
        InputStream is = url.openStream(); // URL 객체가 가리키는 주소에 있는 데이터를 읽어오기 위한 입력스트림 얻음
        int a;
        while((a=is.read())!=-1) {
            System.out.print((char)a);
        }
    }
}
cs

해당 페이지의 HTMl 언어가 나온 것을 확인할 수 있습니다.

 

 

 

 

 

위에서 사용한 채팅 프로그램과 비슷한 채팅 프로그램 예제입니다.

 

chatserver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.io.*;
import java.net.*;
 
public class chatserver {
    public static void main(String[] args) {
        ServerSocket ss;
        Socket sc;
        BufferedReader in, stdin;
        PrintWriter out;
        try {
            ss=new ServerSocket(1111);
            sc=ss.accept();
            while(true) {
                in=new BufferedReader(new InputStreamReader(sc.getInputStream()));
                out=new PrintWriter(sc.getOutputStream(),true);
                stdin=new BufferedReader(new InputStreamReader(System.in));
                
                String inLine=in.readLine();
                if(inLine==null || inLine.equalsIgnoreCase("bye")) { 
                // 클라이언트가 데이터 송신을 중단하거나 'bye'를 입력하면 클라이언트에게 'Disconnected...'메시지를 전송하고 입출력 스트림,소켓을 닫고 시스템 종료함
                    out.println("Disconnected....");
                    in.close();
                    out.close();
                    sc.close();
                    ss.close();
                    System.exit(0);
                }
                System.out.println("수신: "+inLine);
                System.out.print("송신: ");
                if((inLine=stdin.readLine())!=null) {
                    out.println(inLine);  // 서버에서 입력한 메시지 전송
                }
            }
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
}
cs

 

chatclient

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.io.*;
import java.net.*;
public class chatclient {
    public static void main(String[] args) {
        Socket sc;
        BufferedReader in, stdin;
        PrintWriter out;
        String inLine=null;
        String host="localhost";
        
        try {
            sc=new Socket(host,1111);
            out=new PrintWriter(sc.getOutputStream(),true);
            in=new BufferedReader(new InputStreamReader(sc.getInputStream()));
            stdin=new BufferedReader(new InputStreamReader(System.in));
            System.out.print("송신: ");
            while(true) {
                if((inLine=stdin.readLine())!=null) {
                    out.println(inLine);
                    System.out.println("수신: "+in.readLine());
                    if(!inLine.equalsIgnoreCase("bye"))  // bye 입력하지 않을 시
                        System.out.print("송신: ");
                    else {
                        in.close();
                        out.close();
                        sc.close();
                        System.exit(0);
                    }
                }
                else {
                    in.close();
                    out.close();
                    sc.close();
                    System.exit(0);
                }
            }
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
}
 
cs

 

 

'It공부 > Java' 카테고리의 다른 글

Eclipse 환경에서 JavaFX 사용하기 (JDK11 버전 이후)  (12) 2020.08.05
10. 스트림과 파일 처리  (0) 2020.07.17
9. 다중 쓰레드  (0) 2020.07.16
8. 그래픽  (0) 2020.07.15
7. 이벤트 프로그래밍 (2)  (0) 2020.07.14
Comments