자바 웹 개발자가 될거야/JAVA
[JAVA] 소켓통신으로 1:1 채팅하기
whitz
2021. 12. 15. 12:04
< 소켓통신으로 1:1 채팅하기 >
- 선을 통해서 데이터가 들어감
- 자바에서 소켓이라는 라이브러리 제공
- 포트번호에 따라 지정한 어플리케이션과 통신
- 서버와 클라이언트 개념을 가짐
· 클라이언트 : 요청하는 쪽
· 서버 : 응답하는 쪽
- 서버부터 먼저 실행되고 클라이언트를 실행해야 함
· 서버는 항상 켜져있는걸로 셋팅하겠다
- 서버소켓
· 반드시 포트번호 기입 ( 10000번 이상을 권장 )
· 무한으로 돌면서 클라이언트 접속을 기다림
· accept() : 클라이언트를 받아옴
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerEx1 {
public static void main(String[] args) {
ServerSocket s = null;
try{
s=new ServerSocket(54321);
System.out.println("Server Start.... " );
while(true) {
Socket s1 = s.accept();
InputStream is = s1.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
System.out.println(ois.readObject());
System.out.println("accept From: " + s1.getInetAddress().toString());
OutputStream os = s1.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject("내이름 Server");
oos.close();
ois.close();
s1.close();
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
- getInetAddress() : 클라이언트 주소를 가져옴
- 서버는 한번 실행시키고 수정하지 말기 그대로 냅두기
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ClientEx1 {
public static void main(String[] args) {
try{
Socket s1 = new Socket("192.168.219.103", 54321);
String str = "client message : hello";
OutputStream out = s1.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(str);
InputStream is = s1.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
System.out.println("server >>> "+ois.readObject());
ois.close();
is.close();
}catch(IOException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
}
- Socket(" ") 에 자신의 IP 주소 넣기
- OutputStream : 보내고 / InputStream : 받기
- 동시에 보내고 받기하려면 스레드로 따로 만들어줘야함
package Socket;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class SimpleServer extends JFrame implements ActionListener{
JTextArea ta;
JTextField tf;
ServerSocket s;
//Socket s1;
DataInputStream din;
DataOutputStream dout;
boolean stop;
SimpleServer(){
//launchFrame();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ta = new JTextArea();
tf = new JTextField("입력해주세요");
tf.addActionListener(this);
setBackground(Color.LIGHT_GRAY);
ta.setEditable(false);
tf.setEnabled(false);
add(new JScrollPane(ta), BorderLayout.CENTER);
add(tf, BorderLayout.SOUTH);
setSize(500, 300);
setVisible(true);
ta.append("서비스 준비중 ....\n");
service();
}
//public void launchFrame(){
//}
// 소켓을 작동시켜주는 서비스
public void service() {
try{
s = new ServerSocket(5432);
while(true){
//ta.append("클라이언트 접속대기중 ....\n");
Socket s1 = s.accept();
ta.append("클라이언트가 접속하였습니다. "+s1.getInetAddress()+"\n");
tf.setEnabled(true);
//ChatThread t = new ChatThread();
ChatThread t = new ChatThread(s1);
t.start();
}
}catch(IOException e ){
ta.append(e.getMessage()+"2");
}
}
@Override
public void actionPerformed(ActionEvent arg0) {
try{
String msg = tf.getText();
ta.append("me : "+msg+"\n");
dout.writeUTF(msg);
tf.setText("");
if(msg.equals("exit")) {
//ta.append("me : exit...\n");
stop = true;
dout.close();
//s1.close();
s.close();
System.exit(0);
}
}catch(IOException e){
ta.append("연결이 종료되었습니다1");
tf.setEnabled(false);
try{
dout.close();
//s1.close();
}catch(Exception e1){}
//ta.append(e.toString());
}
}
public static void main(String[] args) {
new SimpleServer();
}
class ChatThread extends Thread{
Socket s1;
ChatThread(Socket s1){
this.s1 = s1;
}
@Override
public void run() {
try{
dout=new DataOutputStream(s1.getOutputStream());
din = new DataInputStream(s1.getInputStream());
dout.writeUTF("채팅서버에 접속하신것을 환영합니다 ");
while(!stop) {
String msg = din.readUTF();
//if(msg.equals("exit")) stop=true;
//else
ta.append(s1.getInetAddress()+" "+msg+"\n");
}
tf.setEnabled(false);
din.close();
s1.close();
}catch(IOException e){
ta.append("연결이 종료되었습니다3\n");
tf.setEnabled(false);
try{
din.close();
s1.close();
//ta.append(e.getMessage()+" 1 \n");
}catch(Exception e1){}
}
}
}
}
package Socket;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class SimpleClient extends Thread implements ActionListener{
JTextArea ta;
JTextField tf, tf2;
JDialog dialog;
String host;
Socket s1;
DataInputStream din;
DataOutputStream dout;
boolean stop;
SimpleClient(){
launchFrame();
}
public static void main(String[] args) {
new SimpleClient();
}
public void launchFrame(){
JFrame frame = new JFrame("yoon chatting");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ta=new JTextArea();
tf=new JTextField();
tf.addActionListener(this);
frame.setBackground(Color.lightGray);
ta.setEditable(false);
frame.add(new JScrollPane(ta), BorderLayout.CENTER);
frame.add(tf, BorderLayout.SOUTH);
frame.setSize(500, 300);
frame.setVisible(true);
dialog = new JDialog(frame,"Input IP Address ",true);
JLabel label = new JLabel("Input IP Address ");
tf2 = new JTextField("192.168.1.6",15);
tf2.addActionListener(this);
dialog.add(label, BorderLayout.NORTH);
dialog.add(tf2, BorderLayout.CENTER);
dialog.pack();
dialog.setVisible(true);
service();
}
public void service(){
try {
s1 = new Socket(host,5432);
din = new DataInputStream(s1.getInputStream());
dout = new DataOutputStream(s1.getOutputStream());
ta.append(host+" connect complete ...\n");
this.start();
}catch(IOException e){
System.out.println("disconnect....");
System.exit(0);
}
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == tf){
try{
String msg = tf.getText();
ta.append("me: "+msg+"\n");
dout.writeUTF(s1.getInetAddress()+": "+msg);
tf.setText("");
if(msg.equals("exit")) {
//dout.writeUTF(msg);
//ta.append("bye");
stop=true;
dout.close();
s1.close();
System.exit(0);
}else {
}
}catch(IOException e1){
ta.append(e1.getMessage());
}
}else {
host=tf2.getText().trim();
if(host.equals("")) host="localhost";
dialog.dispose();
}
}
@Override
public void run() {
//System.out.println("Thread started ....");
try{
while(!stop){
String msg = din.readUTF();
ta.append("Server :"+msg+"\n");
if(msg.equals("exit")) break;
}
din.close();
s1.close();
System.exit(0);
}catch(IOException e){
ta.append(e.getMessage());
}
}
}
- 클라이언트에서 exit 입력하면 종료됨