IT/OracleLinux-1Z0460

tcp 소켓 프로그래밍

알콩달콩아빠 2022. 5. 11. 12:51
728x90
반응형

안녕하세요

 

뚱보 프로그래머 입니다.

 

리눅스나, DBMS 관련 접속 문제를 다루다보니 소켓관련 내용이 궁금에 찾다가 이렇게 쓰게 되네요

 

과정
1. 서버 프로그램에서는 서버소켓을 사용해서 서버 컴퓨터의 특정포트에서 클라이언트의 연결요청을 처리할 준비를 한다.
2. 클라이언트 프로그램은 접속할 서버의 IP주소와 포트 정보를 가지고 소켓을 생성해서 서버에 연결을 요청한다.
3. 서버소켓은 클라이언트의 연결을 받으면 서버에 새로운 소켓을 생성해서 클라이언트의 소켓과 연결되도록한다.
4. 이제 클라이언트의 소켓과 새로 생성된 서버의 소켓은 서버소켓과 관계없이 일대일 통신을한다.

자바에서는 TCP를 이용한 소켓프로그래밍을 위해 Socket과 ServerSocket클래스를 제공하며 다음과 같은 특징을 가진다.
Socket -  프로세스간의 통신을 담당하며, InputSteam과 OutputStream을 가지고 있다. 이 두 스트림을 통해 프로세스간의 통신(입출력)이 이루어진다.
ServerSocket - 포트와 연결(bind)되어 외부의 연결요청을 기다리다 연견요청을 기다리다 연결요청이 들어오면, Socket을 생성해서 소켓과 소켓간의 통신이 이루어지도록 한다.
한 포트에 하나의 ServerSocket만 연결할 수 있다. (프로토콜이 다르면 같은 포트를 공유할 수 있다.)


0~65535의 범위 사이의 포트번호를 설정가능.

대게 1023번까지는 ftp, telnet과 같은 다른 통신프로그램에서 사용중이므로 다른 포트 사용 권장

 

한대의 호스트에서 서버와 클라이언트 동시구현

package practice2;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.text.SimpleDateFormat;

public class TcpIpServer {
 public static void main(String[] args) throws Exception{
  ServerSocket serverSocket = null;
  
  try{
   serverSocket = new ServerSocket(8888); // 서버소켓 생성시 8888번 포트와 결합
   System.out.println(getTime()+"서버가 준비되었습니다.");
  } catch(IOException e){
   e.printStackTrace();
  }
  
  while(true){
   try{
   System.out.println(getTime() + "연결요청을 기다립니다.");
   //서버소켓은 클라이언트의 연결요청이 올 때까지 실행을 멈추고 계속 기다린다.
   //클라이언트으 ㅣ연결요청이 오면 클라이언트 소켓과 통신할 새로운 소켓을 생성한다.
   Socket socket = serverSocket.accept();//연결요청을 받아서 저장
   System.out.println(getTime()+socket.getInetAddress()+"로부터 연결요청이 들어왔습니다.");
   
   //소켓의 출력스트림을 얻는다.
   OutputStream out = socket.getOutputStream();
   DataOutputStream dos = new DataOutputStream(out);
   
   //연결소켓에 데이터를 보낸다.
   dos.writeUTF("[Notice] Test Message1 from Server.");
   System.out.println(getTime()+"데이터를 전송했습니다.");
  
   dos.close();
   socket.close();
  }catch(IOException e){
   e.printStackTrace();
  }
 }
 }
 
 static String getTime(){
  SimpleDateFormat f = new SimpleDateFormat("[hh:mm:ss]");
  return f.format(new Date());
 }
}


package practice2;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.rmi.ConnectException;

public class TcpIpClient {
 public static void main(String[] args){
  try{
   String serverIp = "127.0.0.1";
   
   System.out.println("서버에 연결중 서버ip : " + serverIp);
   //소켓을 생성하여 연결을 요청
   Socket socket = new Socket(serverIp, 8888);
   
   //소켓의 인풋 스트림을 얻는다.
   InputStream in = socket.getInputStream();
   DataInputStream dis = new DataInputStream(in);
   
   //소켓으로 부터 받은 파일을 출력
   System.out.println("받은 메시지 " + dis.readUTF());
   System.out.println("연결을 종료합니다.");
   
   dis.close();
   socket.close();
   System.out.println("연결일 종료되었습니다.");
  }catch(ConnectException ce){
   ce.printStackTrace();
  }catch(IOException ie){
   ie.printStackTrace();
  }catch(Exception e){
   e.printStackTrace();
  }
 }
}


서버소켓이 구현이 되어있지않으면 ConnectException발생 

접속 소켓 포트번호알기 getPort()
내 포트 getLocalPort() // 서버 소켓 포트와 포트번호가 같아도됨

serverSocket.setSoTimeout(5*1000); // 접속요청이 5초동안 없으면 socketTimeoutException을 발생시킴

 

 

 채팅 프로그램
package chat1;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class TcpIpServer5 {
 public static void main(String args[]){
  ServerSocket serverSocket = null;
  Socket socket =null;
  
  try{
   serverSocket = new ServerSocket(7777);
   System.out.println("서버가 준비되었습니다.");
   
   socket = serverSocket.accept();
   
   Sender sender = new Sender(socket);
   Receiver receiver = new Receiver(socket);
   
   sender.start();
   receiver.start();
  }catch(Exception e){
   e.printStackTrace();
  }
 }
}

class Sender extends Thread{
 Socket socket;
 DataOutputStream out;
 String name;
  Sender(Socket socket){
   this.socket = socket;
   try{
    out = new DataOutputStream(socket.getOutputStream());
    name = "["+socket.getInetAddress() + ":" + socket.getPort() + "]";
   }catch(Exception e){}
  }
 
  public void run(){
   Scanner scanner = new Scanner(System.in);
   while(out!=null){
    try{
     out.writeUTF(name+scanner.nextLine());
    }catch(IOException e){}
   }
  }
}

class Receiver extends Thread{
 Socket socket;
 DataInputStream in;
 String name;
 Receiver(Socket socket){
   this.socket = socket;
   try{
    in = new DataInputStream(socket.getInputStream());
   }catch(Exception e){}
  }
 
  public void run(){
   while(in!=null){
    try{
     System.out.println(in.readUTF());
    }catch(IOException e){}
   }
  }
}


package chat1;

import java.io.IOException;
import java.net.Socket;
import java.rmi.ConnectException;

public class TcpIpClient5 {
 public static void main(String args[]){
  try{
   String serverIp = "127.0.0.1";
   Socket socket = new Socket(serverIp,7777);
   System.out.println("서버에 연결되었습니다.");
   Sender sender = new Sender(socket);
   Receiver receiver = new Receiver(socket);
   
   sender.start();
   receiver.start();
  }catch(ConnectException e){
   e.printStackTrace();
  }catch(IOException ie){
   ie.printStackTrace();
  }catch(Exception e){
   e.printStackTrace();
  }
 }
}

 

tcp소켓 통신을 하면 보통 netstat 명령어라든지 리슨하고 있는지 이런 것들을 자주 접하게 되는데요

 

한번 해보시면 이해가 좀더 빠르실 듯 합니다.

 

오늘은 2015년 마지막 날이네요 한해 마무리 잘하시고

 

화이팅입니다

728x90
반응형

'IT > OracleLinux-1Z0460' 카테고리의 다른 글

시스템 정보 확인 명령어  (0) 2022.05.19
리눅스 지원 HardWare  (0) 2022.05.11
리눅스 역사  (0) 2022.05.11
리눅스 특징  (0) 2022.05.11
ip 주소 클래스  (0) 2022.05.09