PC ---- NIC ---- HUB ---- HUB ---- ROUTER ---- INTERNET ---- (WEB, FTP, DB)Server
LAN UTP │
│
Intranet ←│→ Internet
│
사설 IP │
172.0.0.1 │ 고정 IP 로만 외부와 연결 가능
192.168.0.1
10.0.0.1
127.0.0.1
IP and Port의 이해
IP는 도시와 같은 위치 정보에 해당합니다.
Port는 항구를 뜻하는 용어로 실제로 네트워크상으로 접속되는 지점을 말합니다.
사용 가능한 포트 : 0 ~ 65535
사용할 수 없는 포트 21 : FTP 23 : Telnet 25 : SMTP 80 : HTTP, IIS등 웹서버 1433 : MS-SQL 기본 포트 3306 : MySQL 기본 포트 1521 : Oracle 기본 포트 8080 : Apache, 기타 웹 서버
1500번 이하는 시스템이 사용하는 포트가 많음으로 1500 이상되는 포트를 사용하기바람
네트워크를 지원하는 java.net 패키지의 기본클래스
URL 클래스
URL 클래스는 웹상에 존재하는 자원에 접근하거나 네트웍상의 유일한 주소를 나타내기 위한 방법을 제공합니다. 또한 위치정보를 관리하기 위한 클래스 입니다. 해당 위치에 스트림을 개설할 수 있습니다.(openStream() 이용)
URL 객체 생성후 스트림 개설
URL객체를 생성할때는 MalformedURLException 에러처리를 해야 합니다.
try{URL uri =newURL("http","hostname",80,"default.htm");InputStream is =uri.openStream(); }catch(MalformedURLException e){e.printStackTrace(); }
URL의 구조
프로토콜://호스트이름: 포트/호스트상의 경로명/파일 의 형태를 지니고 있습니다.
네트워크 연습
URL 클래스를 이용하는 방법
URLMain.java
importjava.net.;importjava.io.;publicclassURLMain{publicstaticvoidmain(String args[]) throwsMalformedURLException,IOException{URL url =newURL("http://www.daum.net:80/index.html");System.out.println("Port: "+url.getPort());System.out.println("Protocol: "+url.getProtocol());System.out.println("HostName: "+url.getHost());System.out.println("File: "+url.getFile());System.out.println("Ref: "+url.getRef());String temp;BufferedReader br; br =newBufferedReader(new InputStreamReader(url.openStream()));while ((temp =br.readLine()) !=null) {System.out.println(temp); }br.close(); } //end of main} //end of URLMain class
URLMain.java
importjava.net.;importjava.io.;publicclassURLMain{publicstaticvoidmain(String args[]) throwsMalformedURLException,IOException{URL url =newURL("http://www.daum.net:80/index.html");System.out.println("Port: "+url.getPort());System.out.println("Protocol: "+url.getProtocol());System.out.println("HostName: "+url.getHost());System.out.println("File: "+url.getFile());System.out.println("Ref: "+url.getRef());String temp;BufferedReader br; //인터넷에서 사용하는 url을 사용하여 데이터를 가지고 옴 url =newURL("https://news.v.daum.net/v/20201005204909700"); br =newBufferedReader(new InputStreamReader(url.openStream()));while ((temp =br.readLine()) !=null) { System.out.println(temp); } br.close(); } //end of main} //end of URLMain class
URLConnection 클래스
URL을 목표지점으로 하는 네트웍 연결을 위한 작업을 수행합니다.
URL객체의 스트림 생성과 URLConnection 객체의 스트림 생성
URL 객체
URL uri = new URL("http", "hostname", 80, "default.htm");
InputStream is = uri.openStream();
URLConnection 객체
URL uri = URL("http", "hostname", 80, "default.htm");
URLConnection con = uri.openConnection();
InputStream is = uri.getInputStream();
또는..
URL uri = URL("http", "hostname", 80, "default.htm");
URLConnection con = uri.openConnection();
con.setDoOutput(true); //스트림방향을 출력으로 설정
OutputStream os = uri.getOutputStream();
URLConnection을 이용한 입력 스트림 개설
URLConnectionMain.java
importjava.net.;importjava.io.;publicclassURLConnectionMain{publicstaticvoidmain(String args[])throwsMalformedURLException,IOException{URL url =newURL("https://www.daum.net"); URLConnection con =url.openConnection();String temp;BufferedReader br; br =newBufferedReader(new InputStreamReader(con.getInputStream()));while ((temp =br.readLine()) !=null) {System.out.println(temp); }br.close(); } //end of main} //end of URLConnectionMain classurl을 이용하여 문서에 대한 정보를 얻어오는 형태
URLConnection.java
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
public class URLConnection {
public static void main(String[] args) throws IOException {
String str = "<https://ssl.pstatic.net/tveta/libs/1306/1306421/c84be064b3aed1368906_20200918171549386.jpg>";
URL url = new URL(str);
java.net.URLConnection conn = url.openConnection();
System.out.println("to String(): " + conn.toString());
int size = conn.getContentLength();
System.out.println("문서 사이즈: " + size); // 파일크기를 자꾸 제대로 못읽어옴
System.out.println("파일 타입" + conn.getContentType());
System.out.println("접속 날짜 " + conn.getDate()); //접속을 얼마나 오랫동안한지 그 시간 리턴
}
}
url을 이용하여 문서 내용을 가져오기
URLConnectionMain.java
importjava.net.;importjava.io.;publicclassURLConnectionMain{publicstaticvoidmain(String args[])throwsMalformedURLException,IOException{URL url =newURL("https://www.daum.net");java.net.URLConnection con =url.openConnection();String temp;BufferedReader br; br =newBufferedReader(new InputStreamReader(con.getInputStream()));while ((temp =br.readLine()) !=null) {System.out.println(temp); }br.close(); } //end of main} //end of Class
url이용 파일 다운로드
URLFileCopy.java
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
public class URLFileCopy {
public static void main(String[] args) throws IOException { //웹서버에서 사진 데이터를 읽어오자.
String str = "<https://pbs.twimg.com/profile_images/1455185376876826625/s1AjSxph_400x400.jpg>";
URL url = new URL(str);
java.io.InputStream in = url.openStream();
BufferedInputStream bi = new BufferedInputStream(in);
FileOutputStream fo = new FileOutputStream("img.jpg");
byte buff[] = new byte[1024];
int imgData = 0;
int cnt = 0;
URLConnection conn = url.openConnection();
int size = conn.getContentLength();
System.out.println("이미지 크기: " +size);
while( (imgData = bi.read(buff)) != -1 ) {
fo.write(buff , 0, imgData); // image의 바이트수가 imgData가 들어가 있다.
fo.flush();
cnt += imgData;
System.out.println(((cnt*100)/size)+"%");
}
in.close(); bi.close(); fo.close();
}
}
간단 하게 서버접속하기
서버 생성
Server.java - 서버 생성
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
int port = 5050;
//서버 소켓을 생성
ServerSocket serverSocket= new ServerSocket(port); //서버 자신의 포트를 설정해준다.
System.out.println("접속 대기중~ ");
while(true) {
Socket sock = serverSocket.accept(); // 새로운 소켓을 생성 클라이언트가 들어왔을때 , 접속했을때 실행되는 구문
System.out.println("사용자 접속 했습니다");
System.out.println("Client ip :"+ sock.getInetAddress());
} //while
}
}
클라이언트 생성
Client.java - 클라이언트 생성
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) throws Exception {
// 연길시에 소켓이 생성된다. 연결이 안될경우에는 예외발생한다.
Socket socket= new Socket("127.0.0.1" , 5050) ;
System.out.println("서버와 접속이 되었습니다.");
}
}
소켓을이용한 데이터 전송
서버
소켓을 이용해 데이터를 전달받을 서버를 생성.
server1.java
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server1 {
public static void main(String[] args) throws IOException,BindException {
int port = 5050;
OutputStream out;
DataOutputStream dataOut;
Socket sock;
ServerSocket serverSocket = new ServerSocket(port); //서버 소켓을 생성
System.out.println("접속 대기중~ "); // C 소켓에서는 listen상태이나 자바에서는 없음
while(true) {
sock = serverSocket.accept(); //실제로 송신을 하는것은 바로 저 sock 객체, 서버 소켓은 대기중에 있다가 외부로 부터 접속이 들어오면 accept()활성하여 클라이언트와 연결 통로인 새로운 소켓 생성
System.out.println("사용자 접속 했습니다");
System.out.println("Client ip :"+ sock.getInetAddress());
//클라이언트와 연결을 하기위한 스트림을 생성한다. //recv, send함수를 통해 데이터를 보내고 받지만 java에서는 소켓을 통해 나가는 스트림, 들어오는 스트림을 만들어 통신하게 됨
out = sock.getOutputStream();
dataOut = new DataOutputStream(out);
dataOut.writeUTF("math:");
dataOut.writeInt(10);
dataOut.flush();
dataOut.close();
sock.close();
}
}
}
클라이언트
Clinet1.java
소켓을 이용해 데이터를 전달할 클라이언트를 생성.
import java.io.DataInputStream;
import java.io.InputStream;
import java.net.Socket;
public class Client1 {
public static void main(String[] args) throws Exception {
// 연길시에 소켓이 생성된다. 연결이 안될경우에는 예외발생한다.
Socket socket = new Socket("127.0.0.1" , 5050) ;
System.out.println("서버와 접속이 되었습니다.");
InputStream in = socket.getInputStream(); //inputstream 과 연결되었
DataInputStream dataIn = new DataInputStream(in);
String str= dataIn.readUTF();
int number = dataIn.readInt(); // 정수형형태로 데이터를 읽어오기 위한 메소드
System.out.println("서버에서 전송된 값 : " + number );
System.out.println("서버에서 전송된 문자 : " + str );
dataIn.close(); in.close(); socket.close();
}
}
정리
컴퓨터-socket-stream-network
ServerSocket 클래스는 외부로 들어오는 접속 정보의 통로 역할을 하는 구멍으로서 정보를 제공하는 역할을 하므로 서버 1개, 클라이언트 여럿을 상대하게 됨
c에서는 소켓을 만들 때 IP 주소가 필요없지만, java 에서는 IP주소가 클래스 내에 포함되어 있어 서버소켓 생성시 ip주소를 입력하는 형태로 되어 있음, 이주소 함께 포트번호를 내부적으로 바인딩시켜줌
서버에는 서버소켓은 들어오는 역할을 하는 통로이고 클라이언트는 다수를 취급하므로 클라이언트와 통신하는 소켓은 별도로 만들어줘야함.
클라이언트가 서버에 접속해오면 별도의 소켓을 하나 더 생성하며 이를 일반적인 Socket클래스에서 다루게 됨
소켓을 통해 스트림이 오고가며 소켓에 스트림을 연결해줘야 합니다.
스트림 생성은 socket.getInputStream()을 InputStream 인스턴스를 생성하게 되며 추가적으로 데이터를 읽기 쉽도록 DataInputStream 추가적으로 연결하게 됩니다.(들어오는 데이터)
반대로 출력스트림은 socket.getOutputStream()을 이용해 OutputStream 인스턴스를 생성하게 됩니다.(외부로 나가는 데이터)
서버에 접속하기 위해서 클라이언트는 인터넷 정보를 수집하게 되는데 이때 이용하는 클래스가 InetAddress이다. 이클래스는 인터넷 주소 정보를 얻어오거나 저장해 두는 역할을 하는 클래스이다.
InetAddress Class
IP주소와 관련된 여러 정보 제공
InetAddress의 객체를 생성하기 위해 스태틱의 getByName()메소들 이용합니다.
AddressTest.java
importjava.net.*;classAddressTest{publicstaticvoidmain(String args[]) throwsUnknownHostException {//객체 선언InetAddress address=null;//현재의 나의 인터넷 주소 정보를 얻어오기 위함 address =InetAddress.getLocalHost();// getLocalHost() 메소드는 static으로 선언된 클래스 메소드임System.out.println("로컬 컴퓨터의 이름 : "+address.getHostName());System.out.println("로컬 컴퓨터의 IP 주소 : "+address.getHostAddress());//특정 사이트의 IP 정보를 얻어오기 위한 정보인 address =InetAddress.getByName("naver.com");System.out.println("naver.com 도메인 이름과 IP 주소 : "+address);//특정 사이트의 여러 IP 정보를 얻어오기 위함InetAddress SW[] =InetAddress.getAllByName("naver.com");for (int i=0; i<SW.length; i++){System.out.println(SW[i]); } }}
Socket, ServerSocket
ServerSocket: 클라이언트보다 먼저 실행되어 클라이언트의 접속 요청을 기다리며, 클라이언트가 접속하면 양방향 통신을 할 수 있는 Socket 객체를 생성합니다.
Socket: 다른 Socket과 데이터를 송수신 합니다.
Network 프로그램의 운영순서
Server: ServerSocket 생성
Server: 포트감시 시작, Client의 접속을 기다림
Client: Socket 생성시에 인자 값으로 서버의 IP, PORT를 지정, 서버에 접속 요구
Server: Client의 요구를 받아 Socket 객체 생성
Server: 생성된 Socket 객체를 이용해 Client에게 데이터를 보냄
Client: Socket객체로 데이터를 받고 필요한 데이터를 다시 서버로 전송함
Socket의 처리방식.
ServerSocket에 의해 Client의 접속요청후 생성된 Socket PORT 나, Clinet쪽 Socket PORT는 무작위로 발생 합니다.
네트웍으로 출력하는 경우 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream())); writer.write("왕눈이 서버에 접속 하신것을 환영 합니다."); writer.flush();
네트웍에서 읽어오는 경우 BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line = reader.readLine();
서버측 소켓 생성
TestServer.java(서버측)
importjava.io.;importjava.net.;publicclassTestServer {publicstaticvoidmain(String[] args) {System.out.println("***** 개발자_1 서버 프로그램 작동됨 *****");ServerSocket server =null;try {//2022 포트로 ServerSocket 생성 server =newServerSocket(2022);while(true) { // 데몬이 되기 위한 무한 루프System.out.println("클라이언트 접속을 대기중입니다.");Socket client =server.accept(); //LockInetAddress ia =client.getInetAddress();int port =client.getLocalPort();// 접속에 사용된 PORTString ip =ia.getHostAddress(); // 원격 Client IPSystem.out.println("클라이언트 접속:"+" Local Port: "+ port +" IP: "+ ip);//한글을 출력할 수 있습니다.//Client로 출력할 객체 생성BufferedWriter writer =newBufferedWriter(new OutputStreamWriter(client.getOutputStream()));//버퍼에 문자열을 기록함writer.write("개발자_1 서버에 접속 하신것을 환영 합니다.");//실제로 Client로 전송함writer.flush();try {client.close(); //소켓 닫음 } catch(IOException e) {System.out.println("Socket을 닫는중 에러 났습니다."+e.toString()); } } }catch(IOException ioe) {System.err.println("Exception generated..."); } finally {try {server.close();System.out.println("서버 작동을 종료합니다."); } catch(IOException e) {System.out.println("ServerSocket을 닫는중 에러 났습니다."+e.toString()); } }//아무키나 누를 때까지 대기합니다.try{InputStream is =System.in;is.read(); }catch(Exception e){ }System.out.println("서버 프로그램 실행을 종료합니다."); }}
클라이언트 측 소켓 생성
TestClient.java(클라이언트 측)
import java.io.;
import java.net.;
public class TestClient {
public static void main(String[] args) {
System.out.println("클라이언트 프로그램 작동.....");
Socket socket = null;
try {
//args[0]: 접속할 지역의 IP
//2022: 접속할 Server Port
socket = new Socket(args[0], 2022);
System.out.println("서버에 연결 되었습니다....");
InetAddress ia = socket.getInetAddress();
int port = socket.getLocalPort();// 접속에 사용된 PORT
String ip = ia.getHostAddress(); // 원격 Client IP
System.out.println("접속한 서버 정보:" + " Local Port: "+ port + " IP: " + ip);
//서버로부터 데이터를 입력받아 버퍼에 저장합니다.
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//버퍼로부터 한 라인씩 읽어 출력합니다.
//Blocking상태에서 기다립니다.
String line = reader.readLine();
System.out.println(line);
} catch(IOException ioe) {
System.err.println("Exception generated...");
} finally {
try {
socket.close();
System.out.println("서버와의 접속을 종료합니다.");
} catch(Exception ignored) {}
}
//아무키나 누를 때까지 대기합니다.
InputStream is = System.in;
try{
is.read();
}catch(Exception e){
}
System.out.println("Client 프로그램 실행을 종료합니다.");
}
}
실행하기
포트보안 문제시 예외 처리
**[시작 -- 설정 -- 제어판 -- Windows 방화벽]**에서 2022 포트를 **[예외]**로 등록합니다.
서버 실행
C:
cd C:\서버폴더 경로
java TestServer
Client 실행
C:
cd C:\클라이언트 폴더 경로
java TestClient 127.0.0.1 2022