서버 부분
서버 쓰레드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.List;
public class ServerThread extends Thread {
Socket socket;
List<Socket> list;
public ServerThread(Socket socket, List<Socket> list) {
this.socket = socket;
this.list = list;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
// 1. recv
try {
while (true) {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = reader.readLine();
System.out.println("클라이언트로 부터 받은 메시지 " + str);
// 2. send
for(Socket sock : list) {
//담당자 소켓
//본인을 제외하고 받고싶을때
if(socket != sock) {
PrintWriter writer = new PrintWriter(sock.getOutputStream());
writer.println(str); // 실질적으로 전송
writer.flush(); // 중요 끝맺음
}
}
Thread.sleep(300);
}
} catch (InterruptedException e) {
e.printStackTrace();
}catch (Exception e) {
// e.printStackTrace();
System.out.println("연결이 끊긴 IP: " + socket.getInetAddress());
list.remove(socket);
// 남은 클라이언트 확인
for (Socket s : list) {
System.out.println("접속 되어있는 IP:" + s.getInetAddress()
+ " Port: "+ s.getPort());
}
try {
socket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
메인파트
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class mainClass {
public static void main(String[] args) {
Socket clientSocket = null;
try {
// 문지기 소켓
ServerSocket serverSocket = new ServerSocket(9000);
// 자동으로 자신의 IP를 설정, binding, listen 포함
List<Socket> list = new ArrayList<Socket>();
while (true) {
System.out.println("접속 대기중...");
clientSocket = serverSocket.accept();
list.add(clientSocket);
// 담당자 소켓
// 어떤 클라이언트의 IP
System.out.println("client IP:" + clientSocket.getInetAddress() + "Port:" + clientSocket.getPort());
// 1. recv
// 문지기 소켓이 아니다
BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
new ServerThread(clientSocket, list).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
클라이언트 부분
VIew 부분, Controller 부분, main부분(실행), ReadTread(쓰레드 읽기), Singleton으로 나눠서 진행하였다.
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ClientView extends JFrame {
JLabel statusLabel;
JTextArea area;
JTextField textField;
JButton sendBtn;
public ClientView() {
super("채팅 프로그램");
setLayout(null);
area = new JTextArea();
area.setLineWrap(true);
JScrollPane scrPane = new JScrollPane(area);
scrPane.setPreferredSize(new Dimension(400, 300));
textField = new JTextField();
sendBtn = new JButton("전송");
statusLabel = new JLabel("온라인 접속 상태");
statusLabel.setBounds(20, 10, 200, 30);
area.setBounds(80, 40, 300, 600);
textField.setBounds(80, 700, 200, 40);
sendBtn.setBounds(300, 700, 80, 40);
add(scrPane);
add(area);
add(textField);
add(sendBtn);
setSize(1200, 800);
setLocation(100, 0);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
단순한 뷰만 들어있는 java class 뷰의 관리는 싱글톤을 활용하여 하기로 하였다.
싱글톤 파트
public class Singleton {
private static Singleton s = null;
ClientView client = new ClientView();
private Singleton() {
}
public static Singleton getInstance() {
if(s == null) {
s = new Singleton();
}
return s;
}
}
뷰를 관리하기위해서 싱글톤 패턴을 생성하였다.
ReadThread
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
public class ReadThread extends Thread {
// 클라이언트단은 받기만 하면 된다.
Socket socket;
public ReadThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
super.run();
while (true) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Singleton s = Singleton.getInstance();
String str = reader.readLine();
System.out.println("서버로 부터 받은 메시지 " + str);
s.client.area.append(str + "\n");
// s.client.area
Thread.sleep(300);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
서버로부터 데이터를 수신받기 위해 만든 클래스
서버로 부터 데이터를 받은걸 append를 통해 View에 값을 추가해준다.
ClientController
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
public class ClientController {
public ClientController() {
InetSocketAddress sockAddress = new InetSocketAddress("192.168.2.5", 9000);
Socket socket = new Socket();
Singleton s = Singleton.getInstance();
s.client.sendBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showConfirmDialog(null, "test");
if (!s.client.textField.getText().equals("")) {
PrintWriter writer;
try {
writer = new PrintWriter(socket.getOutputStream());
System.out.println("전송 문자열: ");
String msg = s.client.textField.getText() + "\n";
// s.client.area.append(msg);
writer.println(msg);
writer.flush();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
try {
socket.connect(sockAddress, 10000);
InetAddress inetAdddress;
if ((inetAdddress = socket.getInetAddress()) != null) {
s.client.textField.setText("서버 연결 성공 :" + inetAdddress);
} else {
s.client.textField.setText("서버 연결 실패");
}
new ReadThread(socket).start();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
뷰의 데이터를 조작하는 ClientController이다.
클릭시에 writer를 통해 서버에 데이터를 전송하도록 하였고
쓰레드는 계속 돌면서 데이터가 올때 받는다.
메인클래스 (실행 파트)
public class mainClass {
public static void main(String[] args) {
new ClientController();
}
}
결과창
'Java > java 기초' 카테고리의 다른 글
쓰레드를 활용한 오브젝트 전송하기 (0) | 2019.12.10 |
---|---|
쓰레드 공부하기 (0) | 2019.12.10 |
네트워크 공부 (0) | 2019.12.09 |
awt - 이미지 올리기 (0) | 2019.12.06 |
awt로 가위바위보 프로그램 만들기 (0) | 2019.12.05 |