1. TCP 통신
서버
package net;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
//TCP => Server
//Network => 송, 수신 [byte] => 내용을 출력 String
public class tcp_server {
public static void main(String[] args) {
new tcp_open();
}
}
class tcp_open{
int port = 11000;
ServerSocket ss = null; //해당 포트를 이용하여 TCP를 활성함
Socket sc = null; //외부 Client가 접속을 할 수 있도록 허가 accept
//메세지 수신
/*// 방법 1
InputStream is = null;
byte data[] = null;
String message = null;
*/
// 방법 2
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
public tcp_open() {
try {
this.ss = new ServerSocket(this.port);
this.tcp_chat(); //통신을 하도록 해당 메소드로 전달
}catch (Exception e) {
System.out.println("서버 포트 오류");
}
}
private void tcp_chat() {
try {
System.out.println("[서버 오픈]");
for(;;) { //반복문으로 통신 접속을 유지시킴
this.sc = this.ss.accept(); //클라이언트 접속 현황
this.is = this.sc.getInputStream();
//byte를 String으로 변환시 언어셋을 세팅하면 한글이 깨짐없이 출력
this.isr = new InputStreamReader(this.is, Charset.forName("UTF-8"));
this.br = new BufferedReader(this.isr); //메모리에 전송된 내용을 임시저장
System.out.println(this.br.readLine()); //출력
}
}catch (Exception e) {
System.out.println("서버 ip 오류");
}finally {
try { //이거 쓰기 싫으면 throws Exception 사용
br.close();
isr.close();
is.close();
}catch (Exception e) {
System.out.println("서버 소켓 close 오류");
}
}
}
}
클라이언트
package net;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
//TCP => Client
public class tcp_client {
public static void main(String[] args) {
new client_chat();
}
}
class client_chat{
private final String serverip = "127.0.0.1";// = localhost = 내아이피
final int port = 11000; //접근 가능한 서버포트
Socket sk = null; //서버에 해당 포트로 연결
Scanner sc = new Scanner(System.in); //InputStream(System.in); 으로 받아도 똑같음
String message = null; //클라이언트가 문자를 입력한 값을 변수에 저장
OutputStream os = null; //서버로 전송하는 Stream
//UDP는 패킷 ! TCP는 소켓 !
public client_chat() {
this.chat();
}
private void chat() {
try {
int connect = 0;
for(;;) {
//서버에 해당 소켓으로 연결을 실행
this.sk = new Socket(this.serverip, this.port);
if (connect == 0) {
System.out.println("서버 접속 완료");
connect++;
}
System.out.println("메세지를 입력하세요 : ");
this.message = this.sc.nextLine();
//exit라는 메세지 입력시 무한반복문 정지로 네트워크 종료
if(this.message.equals("exit")) {
break;
}
//서버에 소켓통신으로 해당 내용을 byte로 전송
this.os = this.sk.getOutputStream();
this.os.write(this.message.getBytes()); //문자를 바이트로 변경
this.os.flush();
this.os.close();
}
}catch (Exception e) {
System.out.println("서버에 접근이 불가능합니다.");
}finally {
this.sc.close();
}
}
}
2. UDP 통신
서버
package net;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.charset.Charset;
//UDP => Server
public class udp_server {
public static void main(String[] args) {
new udp_open();
}
}
/*
TCP는 많은 단계를 거쳐야하지만
UDP는 패킷으로 바로 받을수 있어서 빠름
*/
class udp_open{
private final int port = 11000;
DatagramSocket ds = null; //해당 UDP 포트 오픈
DatagramPacket dp = null; //메세지 송수신 역할
String message = null; //클라이언트 메세지 수신값 받는 역할
public udp_open() {
try {
this.ds = new DatagramSocket(this.port); //서버 오픈
this.server_chat();
}catch (Exception e) {
System.out.println("UDP 포트 오류");
}
}
private void server_chat() {
try {
for(;;) {
System.out.println("서버 오픈");
byte msg[] = new byte[1024 * 2]; //1024byte = 1KB => 2KB
this.dp = new DatagramPacket(msg, msg.length);
this.ds.receive(this.dp); //소켓으로 패킷 내용을 받음
this.message = new String(this.dp.getData(), Charset.forName("UTF-8")); //패킷을 스트링으로 풀기
// System.out.println(this.dp.getPort()); //Client PORT
// System.out.println(this.dp.getAddress()); //Client IP
System.out.println(this.message);
}
}catch (Exception e) {
System.out.println("오류");
}
}
}
클라이언트
package net;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
//UDP => Client
public class udp_client {
public static void main(String[] args) {
new udp_server_connect();
}
}
//UDP는 서버가 편하고 TCP는 클라가 편함
class udp_server_connect{
private final String ip = "127.0.0.1"; //서버 IP
private int server_port = 11000; //서버 접속 UDP 포트
private int client_port = 12000; //자신이 사용하는 UDP 포트 (내가 내컴터로 보낼거니까 포트 같으면 충돌나서 따로씀)
DatagramSocket ds = null; //UDP 서버 접근
DatagramPacket dp = null; //데이터 송수신
String msg = ""; //데이터를 문자로 받아서 처리
InetAddress ia = null; //서버 IP를 셋팅하는 형태 => DatagramPacket
Scanner sc = null;
//Stream이 하나도 필요없음
public udp_server_connect() {
try{
this.sc = new Scanner(System.in); //그동안 고마웠어... 오늘이 마지막이구나
//접근하고자하는 서버 IP (여기만 TCP 다른곳은 UDP)
this.ia = InetAddress.getByName(this.ip);
//서버에 자신의 UDP 포트 전송
this.ds = new DatagramSocket(this.client_port); //클라포트 넣기 (서버포트는 패킷전송할때 사용)
this.udp_client_chat();
}catch (Exception e) {
System.out.println("클라이언트 포트 충돌 발생");
}
}
private void udp_client_chat() {
try {
for(;;) {
System.out.println("서버에 접속하셨습니다");
System.out.println("메세지를 입력하세요 : ");
this.msg = this.sc.nextLine();
byte data[] = this.msg.getBytes();
this.dp = new DatagramPacket(data, data.length, this.ia, this.server_port);
this.ds.send(this.dp);
System.out.println("서버에 문자 발송");
}
}catch (Exception e) {
System.out.println("서버에 접근이 불가능합니다");
}finally {
try {
this.ds.close();
//ia, dp는 close안해도됨
}catch (Exception e) {
System.out.println("DataSocket이 올바르지 않습니다");
}
}
}
}
3. TCP 멀티 통신
Thread를 이용해서 채팅, 파일전송
서버
package net;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
//메세지 수신 + 파일 수신 (TCP - Server)
public class multi_server {
public static void main(String[] args){
Thread th1 = new m_server(10000); //문자
Thread th2 = new m_server(20000); //파일
th1.start();
th2.start();
// new m_server();
}
}
//멀티 포트를 사용 하나는 메세지 하나는 파일 소켓 별도로 열기
class m_server extends Thread{
private int port = 0;
ServerSocket ss = null;
Socket sk = null;
//byte[] 사용하는 방법
InputStream is = null;
OutputStream os = null;
DataInputStream ds = null;
public m_server(int p) {
this.port = p;
try {
this.ss = new ServerSocket(this.port);
}catch (Exception e) {
System.out.println("서버 포트 충돌");
}
}
@Override
public void run() { //Thread로 각각의 포트 통신
try {
System.out.println("서버 오픈");
while(true) {
this.sk = this.ss.accept();
this.is = this.sk.getInputStream();
if(this.port == 10000) { //문자만 출력
this.is = this.sk.getInputStream(); //클라이언트 전송값 받기
byte msg[] = new byte[1024 * 2]; //2KB씩 받기
this.is.read(msg);
System.out.println(new String(msg)); //메세지 출력
}else if(this.port == 20000) { //파일을 저장
String url = "/Users/nayeong/Documents/java_etc/server/"; //클라이언트가 전송한 파일을 저장하는 공간
this.ds = new DataInputStream(this.is);
String filename = this.ds.readUTF(); //파일명
byte data[] = new byte[2097152 * 10]; //2MB * 10 = 20MB
this.os = new FileOutputStream(url + filename); //경로 + 파일명 저장
int filesize = 0;
while((filesize = this.is.read(data)) != -1) {
this.os.write(data, 0, filesize);
this.os.flush();
}
System.out.println("파일 업로드 완료");
this.os.close();
this.ds.close();
this.is.close();
}else {
System.out.println("포트 번호 오류");
}
}
}catch (Exception e) {
System.out.println("서버&클라이언트 오류 ");
}finally {
try {
this.sk.close();
}catch (Exception e) {
System.out.println("서버소켓 close 오류");
}
}
}
}
클라이언트
package net;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
//메세지 전송 + 파일 전송 (TCP - Client)
public class multi_client {
public static void main(String[] args) {
new chatting();
}
}
class chatting{
Scanner sc = new Scanner(System.in);
String server_ip = "172.30.1.3"; //서버 접속 아이피
int server_port = 0; //서버 포트 (10000 : 문자, 20000 : 파일)
Socket sk = null;
String msg = null; //전송할 문자
String url = null; //전송할 파일 url 경로 (자신의 PC 파일 경로)
public chatting() {
System.out.println("메뉴를 선택하세요 \n[1. 채팅, 2. 파일전송] : ");
try {
int part = this.sc.nextInt();
if(part == 1) {
this.server_port = 10000;
this.s_chat();
}else if(part ==2) {
this.server_port = 20000;
this.s_file();
}
}catch (Exception e) {
System.out.println("메뉴는 1~2 입력하세요");
}
}
private void s_chat() throws Exception{ //문자 채팅
OutputStream os = null; //서버로 전송
try {
// do {
while(true) {
this.sk = new Socket(this.server_ip, this.server_port);
System.out.println("메세지를 입력하세요 : ");
this.msg = this.sc.nextLine();
os = this.sk.getOutputStream();
os.write(this.msg.getBytes());
os.flush();
os.close();
}
// }while(true);
}catch (Exception e) {
System.out.println("서버에 접근이 불가능합니다");
}finally {
os.close();
this.sk.close();
this.sc.close();
}
}
private void s_file() throws Exception{ // 파일 전송
//자신의 PC에 있는 파일을 읽어들임
InputStream is = null;
BufferedInputStream bs = null;
//파일을 서버로 전송하는 객체
OutputStream os = null;
DataOutputStream dos = null; //파일명, 파일 둘다 보낼 수 있음
try {
// do {
while(true) {
this.sk = new Socket(this.server_ip, this.server_port);
System.out.println("파일을 전송할 경로 및 파일명을 적어주세요 : ");
//상단 메소드에서 이미 Scanner에 값을 입력하였으므로 새롭게 값을 다시 받기 위해서 메모리를 초기화
this.sc = new Scanner(System.in); //스캐너를 초기화시켜줘야함
this.url = this.sc.nextLine(); //경로 및 파일명
File f = new File(this.url); //파일명을 가져오기 위해 선언
//자신의 PC에 있는 파일 전체를 임시 메모리에 등록
is = new FileInputStream(this.url); //url대신 f써도됨
bs = new BufferedInputStream(is);
byte userfile[] = new byte[bs.available()]; //얘는 끊어읽으면 안됨 해당 PC의 모든 파일을 싹 다 읽어서 핸들링해야해서
bs.read(userfile);
//서버로 전송
os = this.sk.getOutputStream();
dos = new DataOutputStream(os);
dos.writeUTF(f.getName()); //파일명(문자)
dos.write(userfile); //파일 전체 용량
dos.flush();
dos.close();
os.close();
bs.close();
is.close();
}
// }while(true);
} catch (Exception e) {
System.out.println("파일 서버에 접근이 불가능합니다");
}finally {
this.sc.close();
}
}
}
4. UDP로 파일 전송
서버
package net;
import java.io.File;
import java.io.FileOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class udp_file_server {
public static void main(String[] args) {
new udpFileServer().receiveFile();
}
}
class udpFileServer {
public void receiveFile() {
int port = 10000; // 포트 번호
DatagramSocket ds = null;
FileOutputStream fos = null;
String url = "/Users/nayeong/Documents/java_etc/server/";
try {
ds = new DatagramSocket(port);
System.out.println("[UDP 파일 서버 시작] 포트: " + port);
new File(url).mkdirs(); // 저장할 폴더 생성
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// 1. 파일 이름 수신
ds.receive(packet);
String fileName = new String(packet.getData(), 0, packet.getLength()).trim();
// 클라이언트 IP 주소 가져오기
InetAddress clientAddress = packet.getAddress();
int clientPort = packet.getPort();
System.out.println("[서버] 파일 이름 수신: " + fileName);
System.out.println("[서버] 클라이언트 IP: " + clientAddress.getHostAddress());
// 저장할 파일 설정
fos = new FileOutputStream(url + fileName);
// 2. 파일 데이터 수신
while (true) {
ds.receive(packet);
String receivedData = new String(packet.getData(), 0, packet.getLength()).trim();
// 파일 전송 종료 신호 확인
if (receivedData.equals("END_OF_FILE")) {
System.out.println("[서버] 파일 수신 완료: " + url + fileName);
System.out
.println("[서버] 전송 완료한 클라이언트 IP: " + clientAddress.getHostAddress());
break;
}
fos.write(packet.getData(), 0, packet.getLength());
fos.flush();
}
fos.close();
ds.close();
} catch (Exception e) {
System.out.println("[서버 오류] " + e.getMessage());
}
}
}
클라이언트
package net;
import java.io.File;
import java.io.FileInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class udp_file_client {
public static void main(String[] args) {
new udpFileClient().sendFile();
}
}
class udpFileClient {
public void sendFile() {
String serverIP = "172.30.1.3"; // 서버 IP
int serverPort = 10000; // 서버 포트
DatagramSocket ds = null;
FileInputStream fis = null;
Scanner sc = new Scanner(System.in);
try {
ds = new DatagramSocket();
InetAddress serverAddress = InetAddress.getByName(serverIP);
System.out.print("전송할 파일 경로 입력: ");
String filePath = sc.nextLine();
File file = new File(filePath);
// 1. 파일 이름 전송
byte[] fileNameBytes = file.getName().getBytes();
DatagramPacket namePacket = new DatagramPacket(fileNameBytes, fileNameBytes.length, serverAddress,
serverPort);
ds.send(namePacket);
System.out.println("[클라이언트] 파일 이름 전송: " + file.getName());
// 2. 파일 데이터 전송
fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
DatagramPacket filePacket = new DatagramPacket(buffer, bytesRead, serverAddress, serverPort);
ds.send(filePacket);
}
// 3. 전송 종료 메시지 전송
byte[] endMessage = "END_OF_FILE".getBytes();
DatagramPacket endPacket = new DatagramPacket(endMessage, endMessage.length, serverAddress, serverPort);
ds.send(endPacket);
System.out.println("[클라이언트] 파일 전송 완료");
fis.close();
ds.close();
} catch (Exception e) {
System.out.println("[클라이언트 오류] " + e.getMessage());
}
}
}