소켓: 떨어진 컴퓨터를 연결하는 것
- 소켓프로그래밍: 소켓을 리용한 통신, 프로세스간 통신에서도 양쪽에 소켓필요
TCP(연결형): 두개의 컴퓨터 통신위해선 컴퓨터들이 연결되어있어야함.
- 연결후통신ex.전화
UDP(비연결형): 연결관계없이 한쪽에서 일방적으로 데이터보내기 가능. 때문에 데이터 손실될수있음
- 연결없이통신ex편지
TCP소켓 프로그래밍-대부분1:1통신. 서버가 먼저 실행되어 클라이언트의 연결요청을 기다리고 있어야 한다.
- 남들이 사용하지 않는 포트번호를 사용하는게좋다.
package kr.or.ddit.basic.tcp;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TcpClient01 {
public static void main(String[] args) throws UnknownHostException, IOException {
/*
내 컴퓨터를 나타내는 방법
1) 원래의 IP주소로 표현하는 방법. 예)192.168.42.138 -상황에따라 바뀜
2) 지정된 IP주소. 예) 127.0.0.1
3) 원래의 컴퓨터 이름. 예) DESKTOP-NRJ0D4G
4) 지정된 컴퓨터 이름. 예) localhost
*/
String serverIp = "192.168.42.138"; //위에 4가지중 아무거나 쓰면됨
System.out.println(serverIp+"서버에 연결중입니다.");
System.out.println();
// 서버의 IP주소와 포트번호를 지정하여 Socket 객체를 생성한다.
// Socket객체는 생성이 완료되면 해당 서버로 요청신호를 보낸다.
Socket socket = new Socket(serverIp, 7777);
// throws UnknownHostException, IOException
// 이 부분 이후는 서버와 연결이 완료된 이후에 실행되는 코드이다.
System.out.println("서버에 연결되었습니다.");
System.out.println();
// 서버에서 보내온 메시지를 받아서 화면에 출력하기
// 상대방이 보내온 데이터는 Socket의 InputStream객체를 이용한다.
// socket.getInputStream()메서드로 입력용 스트림 객체를 구한다.
InputStream is = socket.getInputStream();
DataInputStream dis = new DataInputStream(is);
// 서버가 보내온 자료를 받아서 출력한다. (자료의 입력)
System.out.println("서버에서 보내온 메시지: "+ dis.readUTF());
System.out.println();
System.out.println("연결을 종료합니다.");
//스트림과 소켓 닫기
dis.close();
socket.close();
}
}
package kr.or.ddit.basic.tcp;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer01 {
public static void main(String[] args) throws IOException {
// TCP 소켓 통신을 위해서 ServerSocket객체를 생성한다.
ServerSocket server = new ServerSocket(7777); // throws IOException
System.out.println("서버가 접속을 기다립니다.");
//accept(): 클라이언트에서 연결 요청이 올때까지 기다린다. 연결 요청이 오면 클라이언트와 연결된 Socket객체를 생성해서 반환한다.
Socket socket = server.accept();
//aceept() 이후의 내용은 연결이 완료되어야만 실행된다.
System.out.println("클라이언트와 연결이 완료되었습니다.");
System.out.println();
System.out.println("소켓으로 연결된 상대방에 대한 정보");
System.out.println("IP주소: "+ socket.getInetAddress().getHostAddress()); // socket.getInetAddress()-소켓으로 연결된 상대방에 대한 정보
// getHostAddress()-ip주소
System.out.println("Port번호: "+ socket.getPort());
System.out.println();
System.out.println("소켓으로 연결된 로컬 컴퓨터에 대한 정보");
System.out.println("IP주소: "+ socket.getLocalAddress());
System.out.println("Port번호: "+ socket.getLocalPort());
// 클라이언트에게 메시지 보내기
// Socket의 OutputStream객체를 이용하여 전송한다.
// socket.getOutputStream()메서드를 이용하여 출력용 스트림 객체를 구할 수 있다.
OutputStream out = socket.getOutputStream(); //바이트 기반 스트림을
DataOutputStream dos = new DataOutputStream(out); //변환
// 클라이언트에 메시지를 보낸다. (클라이언트로 출력하는 방식으로 처리한다.)
dos.writeUTF("아배고파. 아집에갈래");
System.out.println("클라이언트에게 메시지를 보냈습니다.");
// 스트림과 소켓닫기
dos.close();
socket.close();
server.close();
}
}
cmd- 위쪽 화살표: 전에 썼던 명령어. cls-내용지우기
채팅예제
스레드만들기
package kr.or.ddit.basic.tcp;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Scanner;
// 이 클래스는 Socket을 통해서 메시지를 보내는 역할만 담당하는 클래스이다.
public class Sender extends Thread {
private Socket socket; //소켓을 저장할 변수
private DataOutputStream dos; //메시지를 보내는 역할만. 전송객체
private String name; // 누가메세지를 보냈는지 구분
private Scanner scan;
// 생성자
public Sender(Socket socket) {// 소켓객체를 받아서 초기화
this.socket = socket;
scan = new Scanner(System.in);
System.out.print("이름 입력: ");
name = scan.nextLine();
try {
dos = new DataOutputStream(socket.getOutputStream());
} catch (Exception e) {
// TODO: handle exception
}
}
@Override
public void run() { //데이터를 입력받아서 전송만해주면됨
while(dos!=null){
try {
dos.writeUTF(name + ":"+scan.nextLine());
} catch (Exception e) {
// TODO: handle exception
}
}
}
}
package kr.or.ddit.basic.tcp;
import java.io.DataInputStream;
import java.net.Socket;
// 이 클래스는 Socket을 통해서 메시지를 받아서 화면에 출력하는 역할을 담당한다.
public class Receiver extends Thread{
private Socket socket;
private DataInputStream dis; //데이터를 입력 받음
public Receiver(Socket socket) {
this.socket = socket;
try {
dis = new DataInputStream(socket.getInputStream());
} catch (Exception e) {
// TODO: handle exception
}
}
@Override
public void run() {
while(dis!=null){
try {
System.out.println(dis.readUTF());
} catch (Exception e) {
// TODO: handle exception
}
}
}
}
클래스 만들기
package kr.or.ddit.basic.tcp;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer02 {
public static void main(String[] args) {
// ServerSocket 객체를 만들고,
클라이언트가 접속해오면 Socket을 만들어서 메시지를 보내는 클래스와 메시지를 받는 클래스에
이 Socket을 넘겨준다.
try {
ServerSocket server = new ServerSocket(7777);
System.out.println("서버가 준비중입니다.");
Socket socket = server.accept();
Sender sender = new Sender(socket);
Receiver receiver = new Receiver(socket);
sender.start();
receiver.start();
} catch (IOException e) {
}
}
}
package kr.or.ddit.basic.tcp;
import java.net.Socket;
public class TcpClient02 {
public static void main(String[] args) {
try {
Socket socket = new Socket("192.168.42.137", 7777);
System.out.println("서버에 연결되었습니다.");
Sender sender = new Sender(socket);
Receiver receiver = new Receiver(socket);
sender.start();
receiver.start();
} catch (Exception e) {
// TODO: handle exception
}
}
}