[Java] 소켓 프로그래밍

고동이의 IT·2021년 11월 16일
0

Java

목록 보기
31/37
post-thumbnail

소켓: 떨어진 컴퓨터를 연결하는 것

  • 소켓프로그래밍: 소켓을 리용한 통신, 프로세스간 통신에서도 양쪽에 소켓필요

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
		}

	}

}

profile
삐약..뺙뺙

0개의 댓글