(국비교육) 24 - 네트워크 + 아이피 주소 찍기 + 소켓 통신 + 채팅 만들기 + 서블릿으로 게시판 만들
■ 네트워크
네트워크 : 컴퓨터 두 대 이상을 하나의 케이블로 연결함
java.net
* 서버와 클라이언트
- 컴퓨터간의 관계 / 하나의 서버에 여러 클라이언트가 연결된 형태
- 서버 : 서비스를 제공합니다.
- 클라이언트 : 서버가 제공하는 서비스를 제공받는다.
- P2P : 클라이언트가 서버 역할을 동시에 수행하는 것
* IP : 네트워크 상에서 고유한 자신의 주소.
- IPV4 : 173.100.116.50 / 192.168.0.1
- IPV6 (128비트) FFED:0:0:0:0:BA98:3210:4562
* port
ftp: 21 ssh: 22 http: 80 mariadb: 3306 oracle: 1502 mail: 25
■ 아이피 주소 찍어보기
자바에서 IP 주소를 표현할때 사용하는 클래스
InetAddress import 하여 부르기
그리고 이를 배열에 넣어주는 변수도 선언
네이버 아이피 주소 얻어오기
아래는 try catch 로 잡아준다.
■ 내 아이피 주소 찍기
getLocalHost() : 내 아이피 찍기
package jul04;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Iterator;
//Net
/*
* 네트워크 : 컴퓨터 두 대 이상을 하나의 케이블로 연결함
* java.net
*
* 서버와 클라이언트
* 컴퓨터간의 관계 / 하나의 서버에 여러 클라이언트가 연결된 형태
* 서버 : 서비스를 제공합니다.
* 클라이언트 : 서버가 제공하는 서비스를 제공받아요.
*
* P2P : 클라이언트가 서버 역할을 동시에 수행하는 것.
*
* ip : 네트워크 상에서 고유한 자신의 주소
* IPV4 : 173.100.116.50 / 192.168.0.1
* IPV6 (128비트) FFED:0:0:0:0:BA98:3210:4562
*
* port
* ftp: 21 ssh: 22 http: 80 mariadb: 3306 oracle: 1502 mail: 25
*/
public class Net01 {
public static void main(String[] args) {
InetAddress ip = null;
InetAddress[] ipArr = null;
try {
ip = InetAddress.getByName("www.naver.com");
System.out.println("getHostName : " + ip.getHostName());
System.out.println("getHostAddr : " + ip.getHostAddress());
System.out.println("문자열로 보기 : " + ip.toString());
byte[] ipAddr = ip.getAddress();
System.out.println("getHostAddr : " + Arrays.toString(ipAddr));
String result = "";
for (int i = 0; i < ipAddr.length; i++) {
result += ipAddr[i] < 0 ? ipAddr[i] + 256 : ipAddr[i];
result += ".";
}
System.out.println("getAddr() + 256 : " + result);
} catch (UnknownHostException e) {
e.printStackTrace();
}
System.out.println("==================================================");
//내 아이피 찍기
try {
ip = InetAddress.getLocalHost();
System.out.println("getHostName : " + ip.getHostName());
System.out.println("getHostAddr : " + ip.getHostAddress());
System.out.println("문자열로 : " + ip.toString());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
■ 원하는 url 정보 모두 가져오기
스트림 만들고 -> 스트림 리더 만들고 -> 버퍼 리더 만들어준다.
package jul04;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
public class NetStream {
public static void main(String[] args) {
URL url = null;
BufferedReader br = null;
String address = "https://blog.naver.com/wisejia"; //443 보안서버
try {
url = new URL(address);
InputStream ins = url.openStream();
br = new BufferedReader(new InputStreamReader(ins));
String line = "";
while ((line = br.readLine()) !=null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
■ URL 주소로 정보 얻어오기
package jul04;
import java.net.MalformedURLException;
import java.net.URL;
//URL 주소로 정보 얻어오기
public class URLNet01 {
public static void main(String[] args) {
URL url;
try {
url = new URL("https://www.clien.net/service/board/news/18166800?od=T31&po=0&category=0&groupCd=");
System.out.println("url.getAuthority : " + url.getAuthority());
System.out.println("url.getContent : " + url.getContent());
System.out.println("url.getDefaultPort : " + url.getDefaultPort());
System.out.println("url.getFile : " + url.getFile());
System.out.println("url.getHost() : " + url.getHost());
System.out.println("url.getPath() : " + url.getPath());
System.out.println("url.getProtocol() : " + url.getProtocol());
System.out.println("url.getQuery() : " + url.getQuery());
System.out.println("url.getRef() : " + url.getRef());
System.out.println("url.getUserInfo() : " + url.getUserInfo());
System.out.println("url.toExternalForm() : " + url.toExternalForm());
System.out.println("url.toURI() : " + url.toURI());
} catch (Exception e) {
e.printStackTrace();
}
}
}
■ 소켓통신
소켓을 이용하는 통신 프로그램
소켓 : 프로세스간 통신에 사용되는 양 끝단을 이야기합니다.
java.net 안에 있습니다. tcp/udp 를 사용하는 소켓프로그램이 대표적입니다.
TCP/IP
소켓 : TCP/IP 기반 네트워크 통신에서 데이터 송수신의 마지막 접점을 말합니다.
소켓 통신은 이러한 소켓을 통해 서버와 클라이언트 간 통신을 주고받는
양방향 연결 지향성 통신을 말합니다.
소켓통신은 보통 지속적으로 연결을 유지하면서 실시간으로 데이터를
주고 받아야 하는 경우 사용됩니다.
소켓은 서버/클라이언트 소켓으로 구분됩니다.
소켓간 통신을 위해서는 네트워크 간 클라이언트와 서버에 해당하는
컴퓨터를 식별하기 위한 IP주소와 해당 컴퓨터 내에서 현재 통신에
사용되는 응용 프로그램을 식별하기 위한 포트번호가 사용됩니다.
UDP : 유튜브 : 연결이 확인되면 무조건 전송만 합니다.
TCP : 데이터를 전송하기 전에 먼저 상대편과 연결한 후 데이터를 전송합니다.
전송되었는지 확인하고 실패 시 재전송을 하여 다시 확인합니다.
UDP 보다는 느리지만 완벽하게 전송 받을 수 있다.
package socket;
//소켓통신
/*
* 소켓을 이용하는 통신 프로그램
* 소켓 : 프로세스간 통신에 사용되는 양 끝단을 이야기합니다.
* java.net 안에 있습니다. tcp/udp 를 사용하는 소켓프로그램이 대표적입니다.
* TCP/IP
* 소켓 : TCP/IP 기반 네트워크 통신에서 데이터 송수신의 마지막 접점을 말합니다.
* 소켓 통신은 이러한 소켓을 통해 서버와 클라이언트 간 통신을 주고받는
* 양방향 연결 지향성 통신을 말합니다.
* 소켓통신은 보통 지속적으로 연결을 유지하면서 실시간으로 데이터를
* 주고 받아야 하는 경우 사용됩니다.
*
* 소켓은 서버/클라이언트 소켓으로 구분됩니다.
* 소켓간 통신을 위해서는 네트워크 간 클라이언트와 서버에 해당하는
* 컴퓨터를 식별하기 위한 IP주소와 해당 컴퓨터 내에서 현재 통신에
* 사용되는 응용 프로그램을 식별하기 위한 포트번호가 사용됩니다.
*
*
* UDP : 유튜브 : 연결이 확인되면 무조건 전송만 합니다.
* TCP : 데이터를 전송하기 전에 먼저 상대편과 연결한 후 데이터를 전송합니다.
* 전송되었는지 확인하고 실패 시 재전송을 하여 다시 확인합니다.
*
*/
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Socket01 {
public static String getTime() {
SimpleDateFormat sdf = new SimpleDateFormat("[hh:mm:ss]");
return sdf.format(new Date());
}
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(5000);
System.out.println(getTime() + "접속되었습니다.");
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
System.out.println(getTime() + "접속 대기중 ...");
try {
Socket socket = serverSocket.accept();
System.out.println(getTime() + " " + socket.getInetAddress() + "로부터 요청이 들어욤.");
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataout = new DataOutputStream(outputStream);
//원격 소켓 보내기
dataout.writeUTF(getTime() + "서버에서 온 메시지 입니다.");
System.out.println(getTime() + "데이터를 전송했습니다.");
dataout.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package socket;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientSocket {
public static void main(String[] args) {
String serverIP = "127.0.0.1"; //localhost
System.out.println("서버에 연결 중입니다." + serverIP);
Socket socket = null;
try {
socket = new Socket(serverIP, 5000);
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
System.out.println("서버에서 보내온 메시지 : " + dis.readUTF());
System.out.println("연결종료");
dis.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
■ 채팅 만들기
package chatting;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;
public class Client01 {
public static void main(String[] args) {
Scanner sc = null;
Socket socket = null;
try {
sc = new Scanner(System.in);
socket = new Socket("localhost", 5000);
// 출력작업
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String txt = "";
while (true) {
System.out.print("내용");
txt = sc.nextLine();
bw.write(txt + "\n");
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
sc.close();
}
}
}
package chatting;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server01 {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
System.out.println("서버 실행합니다.");
serverSocket = new ServerSocket(5000);
Socket s = serverSocket.accept();
System.out.println("접속 성공");
InputStream is = s.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while (true) {
System.out.println(br.readLine());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package chatting;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import javax.swing.*;
public class Client02 implements ActionListener, Runnable {
private Socket socket;
private ObjectInputStream ois;
private ObjectOutputStream oos;
private JFrame jframe; // 윈도우 창
private JTextField jtf; // 채팅 입력란
private JTextArea jta; // 채팅 내용 보여주는 객체
private JLabel jlb1, jlb2; // 라벨
private JPanel jp1, jp2; // 판넬
private String ip; // IP 주소를 저장할 변수
private String id; // 닉네임 저장할 변수
private JButton jbtn; // 종료버튼
public Client02(String argId) {
ip = "172.30.1.19";
id = argId;
jframe = new JFrame("멀티 채팅 ver 1.1");
// 아래에 붙는 코드
jp1 = new JPanel();
jp1.setLayout(new BorderLayout());
jtf = new JTextField(30); // 30문자
jbtn = new JButton("종료"); // 종료 버튼 생성
jp1.add(jbtn, BorderLayout.EAST);
jp1.add(jtf, BorderLayout.CENTER);
// 위쪽에 붙이는 판넬 코드
jp2 = new JPanel(); // 위쪽에 붙는 판넬
jp2.setLayout(new BorderLayout());
jlb1 = new JLabel("대화명 : [[" + id + "]]"); // IP주소 : 127.0.0.1
jlb1.setBackground(Color.YELLOW);
jlb2 = new JLabel("IP 주소 : " + ip); // IP주소 : 127.0.0.1
jlb2.setBackground(Color.GREEN);
jp2.add(jlb1, BorderLayout.CENTER);
jp2.add(jlb2, BorderLayout.EAST);
// 프레임에 붙이는 코드
jta = new JTextArea("", 10, 50);
jta.setBackground(Color.ORANGE);
JScrollPane jsp = new JScrollPane(jta, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
jframe.add(jp1, BorderLayout.SOUTH);
jframe.add(jp2, BorderLayout.NORTH);
jframe.add(jsp, BorderLayout.CENTER);
// 감지기 붙이는 코드
jtf.addActionListener(this);
jbtn.addActionListener(this);
// x클릭시 처리하는 코드 등 정의
jframe.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
try {
oos.writeObject(id + "#exit");
} catch (Exception ee) {
ee.printStackTrace();
}
System.exit(0); // 프로그램종료
} //
@Override
public void windowOpened(WindowEvent e) { // 이벤트 처리
jtf.requestFocus(); // jtf에 포커스를 놓는다.
}
}); // 윈도우 이벤트 처리 끝
jta.setEditable(false); // 편집 X , 채팅 내용 보여주기만 함
jframe.pack(); // 자동 크기 지정
jframe.setResizable(false); // 창 크기 변경 X
jframe.setVisible(true); // 보이기
} // 생성자
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource(); // 이벤트 발생 위치 열기
String msg = jtf.getText(); // 채팅 내용 입력 받기
if (obj == jtf) {
if (msg == null || msg.length() == 0) {
// 경고창
JOptionPane.showMessageDialog(jframe, "글을 쓰세요", "경고", JOptionPane.WARNING_MESSAGE);
} else { // 내용을 입력하고 엔터한 경우
try {
oos.writeObject(id + "#" + msg);
} catch (Exception ee) {
ee.printStackTrace();
}
jtf.setText(""); // jtf를 지운다.
} // else : 내용 0
} else if (obj == jbtn) { // 종료 버튼 클릭
try {
oos.writeObject(id + "#exit");
} catch (Exception ee) {
ee.printStackTrace();
}
System.exit(0);
}
}
public void init() {
try {
socket = new Socket(ip, 5000);
System.out.println("서버에 접속되었습니다... 주인님^^");
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
Thread t = new Thread(this);
t.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
Scanner sc = new Scanner(System.in);
String name = "";
do {
System.out.println("이름을 입력하세요.(3글자 이상)");
name = sc.next();
} while (name.length() < 3);
Client02 cc = new Client02(name);
cc.init();
sc.close();
}
@Override
public void run() {
String message = null;
String[] receiveMsg = null;
boolean isStop = false;
while (!isStop) {
try {
message = (String) ois.readObject(); // 채팅내용
receiveMsg = message.split("#");
} catch (Exception e) {
e.printStackTrace();
isStop = true; // 반복문 종료로 설정
}
System.out.println(receiveMsg[0] + " : " + receiveMsg[1]);
if (receiveMsg[1].equals("exit")) {
if (receiveMsg[0].equals(id)) {
System.exit(0);
} else {
jta.append(receiveMsg[0] + "님이 종료했습니다\n");
// 커서를 현재 채팅 내용의 자리에 보여준다.
jta.setCaretPosition(jta.getDocument().getLength());
}
} else {
jta.append(receiveMsg[0] + " : " + receiveMsg[1] + "\n"); // 홍길 : 안녕
// 커서를 현재 채팅 내용의 자리에 보여준다.
jta.setCaretPosition(jta.getDocument().getLength());
}
}
}
}
package chatting;
import java.awt.*;
import java.io.*; // 입출력이 일어난다.
import java.net.*; // 네트워크 프로그램.
import java.util.*; // ArrayList 사용(클라이언트를 담는 역할)
import javax.swing.*;
public class Server02 extends JFrame {
private ArrayList<MultiServerThread> list;
private Socket socket;
JTextArea ta;
JTextField tf;
public Server02() {
// 화면 디자인 코드
setTitle("채팅 서버 ver 1.1");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ta = new JTextArea();
add(new JScrollPane(ta));
tf = new JTextField();
tf.setEditable(false);
add(tf, BorderLayout.SOUTH);
setSize(300, 300);
setVisible(true);
// 채팅 관련 코드
list = new ArrayList<MultiServerThread>();
try {
ServerSocket serverSocket = new ServerSocket(5000);
MultiServerThread mst = null;// 한 사용자 담당할 채팅 객체
boolean isStop = false; // 깃발 값
tf.setText("서버 정상 실행중입니다. 주인님^^\n");
while (!isStop) {
socket = serverSocket.accept();// 클라이언트별 소켓 생성
mst = new MultiServerThread();// 채팅 객체 생성
list.add(mst);// ArrayList에 채팅 객체 하나 담는다.
mst.start();// 쓰레드 시작
} // while
} catch (IOException e) {
e.printStackTrace();
} // catch
}// 생성자
public static void main(String[] args) {
new Server02();
}// main
// 내부 클래스
class MultiServerThread extends Thread {
private ObjectInputStream ois;
private ObjectOutputStream oos;
@Override
public void run() {
boolean isStop = false; // flag value(깃발 값)
try {
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
String message = null; // 채팅 내용을 저장할 변수
while (!isStop) {
message = (String) ois.readObject();// 클라이언트 입력 받기
String[] str = message.split("#");// 홍길동#방가방가
if (str[1].equals("exit")) { // 홍길동#exit, 종료하겠다는 뜻
broadCasting(message);// 모든 사용자에게 내용 전달
isStop = true; // 종료
} else {
broadCasting(message);// 모든 사용자에게 채팅 내용 전달
} // else
} // while
list.remove(this);// 홍길동을 뺀다.
ta.append(socket.getInetAddress() + " IP 주소의 사용자께서 종료하셨습니다.\n");
tf.setText("남은 사용자 수 : " + list.size());
} catch (Exception e) {
list.remove(this);// 장길산을 뺀다.
ta.append(socket.getInetAddress() + " IP 주소의 사용자께서 비정상 종료하셨습니다.");
tf.setText("남은 사용자 수 : " + list.size());
} // catch
}// run
public void broadCasting(String message) {// 모두에게 전송
for (MultiServerThread ct : list) {
ct.send(message);
} // for
}// broadCasting
public void send(String message) { // 한 사용자에게 전송
try {
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
} // catch
}// send
}// 내부 클래스
}// end
■ 서블릿을 활용한 보드 열기
list 라는 이름으로 boardList 를 보낸다.
사이즈 늘어나는 것 방지
JSP/Servlet | 서블릿과 JSP/HTML | JSP에 전달하고 결과를 forward하여 표시
또 다른 방법은 포워드로 결과를 표시하는 JSP에 표시를 전환하는 것이다. 서블릿에서 결과를 표시하는 JSP를 포워드(forward)로 표시 시키면 서블릿에서 화면의 표시 등을 할 필요는 없다. 단, 이
www.devkuma.com
Color Code :: 색상표 | 색상 :: SAEKSANG.COM
Color Code :: 색상표 | 색상 :: SAEKSANG.COM
색상닷컴 :: SAEKSAG.COM
saeksang.com