java socket프로그래밍 관련 질문입니다.
글쓴이: ehyuck / 작성시간: 금, 2020/11/27 - 12:48오후
소켓 프로그래밍 관련 질문입니다. 멀티쓰레드 환경으로 여러개의 채팅방을 구현하려는 코드를 작성중입니다.
그래서 제가 구현한 방식은 client가 server에게 다른 client와 채팅요청을 하면 받아지면, 둘의 채팅방이 생겨서 서로 대화하는 형식입니다. 그 채팅방에서 친구를 추가할 수 있는 기능도 구현을 생각하고 있습니다. 하지만. 두명에서 1:1 채팅가지는 지금 되고 있는 상태인데, 3명부터는 채팅이 추가하지 않은 클라이언트에게java.lang.NullPointerException
오류가 나오고, 그 뒤로 소켓을 읽어오지 않습니다.(broadcast를 해주었음에도 불구하고)
server의 코드입니다.
package Mypackage; import java.io.IOException; import java.util.Iterator; import java.sql.*; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Set; import java.util.HashSet; import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class LoginServer { private static Set<String> userlist = new HashSet<>(); //가입자들의 정보 저장. private static Set<PrintWriter> writers = new HashSet<>(); private static Set<String> chatList = new HashSet<>(); public static void main(String[] args) throws Exception { System.out.println("The chat server is running..."); ExecutorService pool = Executors.newFixedThreadPool(500); try (ServerSocket listener = new ServerSocket(59001)) { while (true) { pool.execute(new Handler(listener.accept())); } } } private static class Handler implements Runnable { private String id; private Socket socket; private Scanner in; private PrintWriter out; private String pw; private String logid=""; String DB_URL = "jdbc:mysql://localhost/userlist?serverTimezone=UTC"; //접속할 DB 서버 Connection conn=null; Statement state=null; public Handler(Socket socket) { this.socket = socket; } public void run() { try { in = new Scanner(socket.getInputStream()); out = new PrintWriter(socket.getOutputStream(), true); Class.forName("com.mysql.cj.jdbc.Driver"); //mysql driver conn=DriverManager.getConnection(DB_URL,"root","jang14"); //db주소와, 사용자, 비밀번호를 통해서 접근. state=conn.createStatement(); //mysql 연결 boolean realuser=false; Statement state9=conn.createStatement(); String list="select userid from info"; ResultSet ulist=state9.executeQuery(list);//데이터베이스의 userid를 다 가져옴. while(ulist.next()) { userlist.add(ulist.getString("userid"));//데이터베이스에서 가져온 userid를 server의 hashlist에저장. } writers.add(out); while(true) { String input=in.nextLine(); System.out.println(input); if(input.startsWith("logid")) //client에서 logid가 왔을 때, 로그인 { String[]info=input.split(" "); //id와 password가 같이와서 나눠줌. id=info[0].substring(5); //id pw=info[1]; //password String sqlid="select userid from info where userid like"+"'"+id+"'"; ResultSet rsi=state.executeQuery(sqlid); if ((rsi.next() == false || (id.isEmpty()) == true)) { out.println("id invalid"); //로그인 실패 } rsi.close(); Statement state2=conn.createStatement(); String sql="select * from info where userid like"+"'"+id+"'"; //id를 바탕으로 비밀번호를 찾음 ResultSet rs=state2.executeQuery(sql); //결과 값 저장. Statement state3=conn.createStatement(); while(rs.next()) //데이터베이스 스캔 { String dbpw=rs.getString("password"); //조건문에 맞는 패스워드 저장\ if(pw.equalsIgnoreCase(dbpw)) //입력한 비밀번호와 아이디가 맞을 때, 로그인성공 { out.println("access:"+rs.getString("name")+":"+rs.getString("comment")+":"+id+":"+rs.getString("friend"));//클라이언트에게 성공했다고 보내줌. String sql_update = "update info set login_count = login_count+1, status = true where userid = "+ "'"+id+"'"; state3.executeUpdate(sql_update); logid=id; //로그인 되어있는 아이디 저장. } else { out.println("pw invalid"); //로그인 실패 } } rs.close(); state3.close(); state2.close(); } else if(input.startsWith("Resister")) //회원가입 { String [] nw=input.split(" "); //회원가입되서 온 정보를 나눠줌. String addname=nw[0].substring(8); int addbday=Integer.parseInt(nw[1]); String addemail=nw[2]; String addid=nw[3]; String addpw=nw[4]; String addnick = nw[5]; Statement state4=conn.createStatement(); String mysql="insert into info values("+"'"+addname+"'"+","+addbday+","+"'"+addemail+"'"+","+"'"+addid+"'"+","+"'"+addpw+"'"+","+0+","+"'"+"hello world"+"'"+","+"'"+null+"'"+"," + "'"+addnick+"'"+","+false+","+"'2011210557'"+")"; //String mysql="insert into info values("+"'"+addname+"'"+","+addbday+","+"'"+addemail+"'"+","+"'"+addid+"'"+","+"'"+addpw+"'"+","+0+","+"'"+""+"'"+","+"'"+"hello world"+"'"+")"; //데이터베이스에 저장시켜주는 구문 state4.executeUpdate(mysql); //데이터베이스 업데이트 userlist.add(nw[3]); //가입하면, hashset에 userid 추가 out.println("Welcome"); //회원가입 되었다는 것을 보내줌. state4.close(); } else if(input.startsWith("Search"))//client에서 검색하라고 명령이 왓을경우 { String sid=input.substring(6); Iterator<String>finduser=userlist.iterator(); while(finduser.hasNext()) { String comp=finduser.next(); if(sid.contains(comp)) { realuser=true; //hashset에서 해당 가입자가 있는지 스캔 } } if(realuser==true) //가입자가 있을 경우 , 해당가입자의 정보 출력해서 client에게 보내줌. { String searchinfo="select * from info where userid like '"+sid+"'";//해당아이디의 정보를 찾음 Statement st2=null; st2=conn.createStatement(); ResultSet sch=st2.executeQuery(searchinfo); //찾은 정보를 저장. String fetch=""; while(sch.next()) { fetch="Searching"+sch.getString("name")+" "+sch.getString("birthday")+" "+sch.getString("email")+" "+sch.getString("comment"); //찾은 정보를 보내줌. } System.out.println(fetch); out.println(fetch); st2.close(); realuser=false; } else if(realuser==false) //해당가입자가 없을 경우 client에게 보내줌. { out.println("No user"); } } else if(input.startsWith("ADDF")) //친구를 추가할때, { boolean check=false; String take="select friend from info where userid like"+"'"+logid+"'"; //현재 로그인되어 있는 사용자의 친구명단을 읽어옴. Statement state6=conn.createStatement(); ResultSet fri=state6.executeQuery(take); String prev=""; while(fri.next()) { prev=fri.getString("friend"); //그 전에 있던 친구명단을 가져옴. } String ptocol=input.substring(4); //추가할 친구id를 가져옴 Iterator <String> afinduser=userlist.iterator(); //친구로 추가할 id가 실제로 가입자인지 스캔 while(afinduser.hasNext()) { String comp2=afinduser.next(); if(ptocol.contains(comp2)) { check=true; //있으면 true로 바꿔줌 } } if(check==true) //가입자가 있을 경우, 친구 추가 진행 { if(prev!=null&&prev.contains(ptocol)) { //친구리스트에 친구가 겹치는 경우 out.println("DUPLICATION"); } else { String flist=prev+" "+ptocol; //새로 친구리스트를 만들어줌 state6.close(); String fradd="update info set friend="+"'"+flist+"'"+"where userid like"+"'"+logid+"'"; //데이터베이스에 반영시켜줌 Statement state7=conn.createStatement(); state7.executeUpdate(fradd); state7.close(); out.println("ADD"); //client에게 추가했다고 보내줌. check=false; } } else if(check==false) //가입자가 없을 경우, 사용자가 없다고 client에 보내줌. { out.println("No user"); } } else if(input.startsWith("List")) //client에서 친구 리스트가 필요하다고 왓을때 { String obj=input.substring(4); //리스트가 필요한 로그인 사용자 id를 불러온다. String comma="select friend from info where userid like"+"'"+obj+"'"; //해당 id의 친구 리스트 저장 Statement state8=conn.createStatement(); ResultSet frlist=state8.executeQuery(comma); //친구 리스트 조회 String temp=""; while(frlist.next()) { temp=temp+frlist.getString("friend"); //temp에 친구리스트 저장 } out.println("Frlist"+temp); //client에 친구리스트를 보내줌. } else if(input.startsWith("ChangeInfo")) { // 내정보 변경 할 때 String[] ch_info = input.split(":"); String ch_sql = "update info set nickname = "+"'"+ch_info[1]+"'," + " comment = " + "'"+ch_info[2]+"'"+" where userid = " +"'"+logid+"'";// 닉네임이랑 상태메시지 변경함 Statement state10 = conn.createStatement(); state10.executeUpdate(ch_sql); state10.close(); } else if(input.startsWith("chatting TEXT")) { String msg = input.substring(13); String [] talk=msg.split(":"); for (PrintWriter writer : writers) { writer.println("Message" +talk[0]+ ": "+talk[1]); } } else if(input.startsWith("LOGOUT")) { String logout_time = input.substring(6); int time = Integer.parseInt(logout_time); String time_update = "update info set time = " + "'"+time+"'" + ", status = false where userid = " + "'" + logid + "'"; Statement state11 = conn.createStatement(); state11.executeUpdate(time_update); state11.close(); } else if(input.startsWith("Start")) { String [] person = input.split(":"); //String person=input.substring(5); for (PrintWriter writer : writers) { writer.println("Request:"+person[1]+":"+person[2]);//client에게 입장알림을 전달. } } else if(input.startsWith("Nop")) { String cancel=input.substring(3); for (PrintWriter writer : writers) { writer.println("Denied"+cancel); } } else if(input.startsWith("Join")) { String chatter=input.substring(4); chatList.add(chatter); for (PrintWriter writer : writers) { writer.println("Message"+chatter+" has joined"); } } else if(input.startsWith("Exit")) { String end=input.substring(4); String []already=end.split(":"); chatList.remove(already[0]); for (PrintWriter writer : writers) { writer.println("Message"+already[0]+" "+"has exited"); } } else if(input.startsWith("Invite")) { boolean ivd=false; String ivmsg=input.substring(6); String [] ivperson=ivmsg.split(":"); Iterator<String>inviuser=userlist.iterator(); while(inviuser.hasNext()) { String comp1=inviuser.next(); if(comp1.contains(ivperson[0])) { ivd=true; //hashset에서 해당 가입자가 있는지 스캔 } } if(ivd=true) { for (PrintWriter writer : writers) { writer.println("Invite:"+ivperson[0]+":"+ivperson[1]); } ivd=false; } else if(ivd==false) { for(PrintWriter writer: writers) { writer.println("No user"); } } } out.flush(); } } catch (Exception e) { System.out.println(e); } finally { if (out != null) { } try { socket.close(); } catch (IOException e){} } } } }
클라이언트 코드입니다.
package Mypackage; import java.awt.event.ActionEvent; import java.util.Date; import java.text.SimpleDateFormat; import java.awt.event.MouseEvent; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.awt.event.MouseAdapter; import java.awt.event.ActionListener; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.net.Socket; import java.util.Arrays; import java.util.HashSet; import java.util.Hashtable; import java.util.Scanner; import java.util.Set; import java.awt.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.net.*; import java.awt.event.MouseEvent; import java.awt.event.MouseAdapter; import javax.swing.ListSelectionModel; import javax.swing.ListModel; import javax.swing.SwingConstants; import Mypackage.SocialDate; public class Login { // static String ip=null; //txt파일에서, ip읽어옴. static int portnum=0; //port number String serverAddress; //서버 주소 Scanner in; PrintWriter out; String curid; //현재 로그인 id //login gui variables JFrame frame=new JFrame("login form"); JLabel lbl,la1,la2,la3,emp; JTextField id; JPasswordField passwd; JPanel emptyPanel,idPanel,paPanel,loginPanel; JButton b1,b2; JTextArea content; //TODO: //메뉴창 JFrame menu_frame; JLabel user_name; JLabel user_state; JPanel menu_p; JButton make_room; JButton add_friend; JList friend_list; DefaultListModel friend_model; JButton change_info; JPopupMenu popupMenu; JMenuItem lookinfo; JMenuItem sendMsg; //채팅방 swing 변수 JFrame room_frame; JTextField sendTF; //보낼 메시지 적는 곳 JLabel la_msg; JTextArea ta; //메시지가 쌓여서 보이는 곳 JScrollPane sp_ta,sp_list; JList<String> user; // 현재 채팅방에 있는 유저 표시 JButton invite_btn,exit_btn; //초대 나가기 버튼 JPanel p; //추가하려는 친구 String relaid; public String encryptSHA256(String str) { String sha=""; try { MessageDigest sh= MessageDigest.getInstance("SHA-256"); sh.update(str.getBytes()); byte[] byteData = sh.digest(); StringBuilder sb=new StringBuilder(); for (byte byteDatum : byteData) { sb.append(Integer.toString((byteDatum & 0xff) + 0x100, 16).substring(1)); } sha=sb.toString(); } catch (NoSuchAlgorithmException e) { System.out.println("암호화 에러-NoSuchAlgorithmException"); sha=null; } return sha; } public Login(String serverAddress) { this.serverAddress=serverAddress; // FlowLayout사용 frame.setLayout( new FlowLayout() ); // Border로 영역 생성 EtchedBorder eborder = new EtchedBorder(); // 레이블 생성 lbl = new JLabel( "Enter Id and Password" ); // 레이블에 영역 만들기 lbl.setBorder(eborder); // 레이블 추가 frame.add(lbl); emptyPanel = new JPanel(); emp = new JLabel("\n"); emptyPanel.add(emp); frame.add(emp); // id패널과 pw 패널생성 idPanel = new JPanel(); paPanel = new JPanel(); la3 = new JLabel("Username"); la2 = new JLabel(" Password"); // id텍스트필드와 pw텍스트 필드 선언 id = new JTextField(20); passwd = new JPasswordField(20); idPanel.add(la3); idPanel.add(id); paPanel.add(la2); paPanel.add(passwd); // 로그인과 회원가입을 위한 패널 생성 loginPanel = new JPanel(); b1 = new JButton("Login"); b2 = new JButton("Resister"); loginPanel.add(emp); loginPanel.add(b1); loginPanel.add(b2); frame.add(emptyPanel); frame.add(emptyPanel); frame.add(idPanel); frame.add(paPanel); frame.add(emptyPanel); frame.add(loginPanel); b1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String comment=e.getActionCommand(); if(comment.contentEquals("Login")) //로그인 버튼을 눌렀을 때, { String logid= id.getText().trim(); //id에 누른 값을 불러옴 String logpw= passwd.getText(); //패스워드에 누른 값을 불러옴. String encryptLogPW = encryptSHA256(logpw); out.println("logid"+logid+" "+encryptLogPW); //서버에게 아이디와 패스워드 전달 if(logid.length()==0 || logpw.length()==0) { JOptionPane.showMessageDialog(null, "아이디 또는 비밀번호를 입력 하셔야 됩니다.", "아이디나 비번을 입력!", JOptionPane.DEFAULT_OPTION); return; } frame.dispose(); } } }); b2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new Resister(); } }); // 3행 20열 영역의 텍스트에어리어 //content = new JTextArea(3,20); //JScrollPane s= new JScrollPane(content); //add(s); frame.setSize( 400, 200 ); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public class Resister { JFrame sub=new JFrame("Resister"); JLabel lbl,namelbl,birthlbl,emaillbl, idlbl,pwlbl,nicklbl; JTextField nameField, birthField,emailField, idField, nickField; JPasswordField passwd; JPanel namePanel,birthPanel, emailPanel, idPanel,paPanel,nickPanel; JButton resister_btn; JTextArea content; public Resister() { sub.setLayout(new FlowLayout()); EtchedBorder eborder = new EtchedBorder(); lbl = new JLabel( "Enter user information" ); // 레이블에 영역 만들기 lbl.setBorder(eborder); sub.add( lbl ); namePanel = new JPanel(); birthPanel = new JPanel(); emailPanel = new JPanel(); idPanel = new JPanel(); paPanel = new JPanel(); nickPanel = new JPanel(); namelbl = new JLabel("User Name"); nameField = new JTextField(10); namePanel.add(namelbl); namePanel.add(nameField); sub.add(namePanel); birthlbl = new JLabel("birthday"); birthField = new JTextField(10); birthPanel.add(birthlbl); birthPanel.add(birthField); sub.add(birthPanel); emaillbl = new JLabel("email"); emailField = new JTextField(10); emailPanel.add(emaillbl); emailPanel.add(emailField); sub.add(emailPanel); idlbl = new JLabel("user Id"); idField = new JTextField(10); idPanel.add(idlbl); idPanel.add(idField); sub.add(idPanel); pwlbl = new JLabel("password"); passwd = new JPasswordField(10); paPanel.add(pwlbl); paPanel.add(passwd); sub.add(paPanel); nicklbl = new JLabel("nick name"); nickField = new JTextField(10); nickPanel.add(nicklbl); nickPanel.add(nickField); sub.add(nickPanel); resister_btn = new JButton("Resister"); sub.add(resister_btn); resister_btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String comment=e.getActionCommand(); if(comment.contentEquals("Resister")) //register버튼 입력시, { String name=nameField.getText(); //이름, 생년월일등을 불러옴 String bday=birthField.getText(); String email=emailField.getText(); String id=idField.getText(); String pw=passwd.getText(); String encryptPW = encryptSHA256(pw); String nick = nickField.getText(); out.println("Resister"+name+" "+bday+" "+email+" "+id+" "+encryptPW + " " + nick); //서버에게 전달. } sub.dispose(); } }); sub.setSize( 250, 350 ); sub.setVisible(true); sub.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } //TODO: public class Chatting_Room { public Chatting_Room(String id) { room_frame = new JFrame(id+"'s chatting room"); sendTF = new JTextField(15); la_msg = new JLabel("Message"); ta = new JTextArea(); ta.setLineWrap(true);//TextArea 가로길이를 벗어나는 text발생시 자동 줄바꿈 user = new JList<String>(); sp_ta = new JScrollPane(ta); sp_list = new JScrollPane(user); invite_btn = new JButton("친구 초대"); exit_btn = new JButton("나가기"); p = new JPanel(); sp_ta.setBounds(10,10,380,390); la_msg.setBounds(10,410,60,30); sendTF.setBounds(70,410,320,30); sp_list.setBounds(400,10,120,350); invite_btn.setBounds(400,370,120,30); exit_btn.setBounds(400,410,120,30); p.setLayout(null); p.setBackground(Color.GRAY); p.add(sp_ta); p.add(la_msg); p.add(sendTF); p.add(sp_list); p.add(invite_btn); p.add(exit_btn); sendTF.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { out.println("chatting TEXT"+curid+":"+sendTF.getText()); sendTF.setText(""); } }); exit_btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getSource() == exit_btn) room_frame.dispose(); } }); invite_btn.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { if(e.getSource()==invite_btn) { new Invite(curid); } } }); room_frame.add(p); room_frame.setBounds(300,200,550,500); room_frame.setVisible(true); room_frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); sendTF.requestFocus(); } } //TODO: public class Menu { public Menu(String name, String comment, String friend) { popupMenu = new JPopupMenu(); lookinfo = new JMenuItem("친구정보보기"); sendMsg = new JMenuItem("채팅신청하기"); popupMenu.add(lookinfo); popupMenu.add(sendMsg); menu_frame = new JFrame("Menu"); user_name = new JLabel(name); user_state = new JLabel(comment); make_room = new JButton("방 만들기"); add_friend=new JButton("친구검색"); friend_list = new JList(new DefaultListModel()); friend_model = (DefaultListModel)friend_list.getModel(); for(String add:friend.split(" ")) { friend_model.addElement(add); } friend_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); friend_list.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { // 오른쪽 버튼 클릭 시 ... if(e.getModifiers() == MouseEvent.BUTTON3_MASK) { // 왼쪽이 1 가운데가 2 오른쪽이 3 BUTTON3_MASK - 오른쪽 버튼 // System.out.println("반응"); popupMenu.show(friend_list, e.getX(), e.getY()); friend_list = (JList)e.getSource(); } } }); lookinfo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String comm=e.getActionCommand(); if(comm.contentEquals("친구정보보기")) { String str = (String)friend_list.getSelectedValue(); out.println("Search"+str); } } }); sendMsg.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String start=e.getActionCommand(); if(start.contentEquals("채팅신청하기")) { Chatting_Room c1=new Chatting_Room(curid); String receiver=(String)friend_list.getSelectedValue(); out.println("Start:"+receiver+":"+curid); System.out.println(receiver); } } }); friend_model.remove(0); // db에 저장된 친구이름이 null로 시작해서 앞에 null 지워줌 change_info = new JButton("정보 수정"); user_name.setBounds(10, 50, 150, 20); user_state.setBounds(10, 80, 350, 15); make_room.setBounds(200, 400, 120, 30); add_friend.setBounds(10, 10, 120, 30); friend_list.setBounds(10, 110, 350, 130); change_info.setBounds(150, 10, 120,30); menu_p = new JPanel(); menu_p.setLayout(null); menu_p.add(add_friend); menu_p.add(change_info); menu_p.add(user_name); menu_p.add(user_state); menu_p.add(friend_list); menu_frame.add(menu_p); menu_frame.setSize(400,300); menu_frame.setVisible(true); //동네예보 SocialDate s = new SocialDate(); JPanel data_p = new JPanel(); data_p.setBackground(Color.GRAY); data_p.setLayout(null); JLabel locationlbl = new JLabel("성남시 수정구 기준시간 : 00시"); locationlbl.setBounds(10,300,300,50); JLabel t1hlbl = new JLabel("기온"); JLabel t1hlbl2 = new JLabel(s.tem); JLabel rehlbl = new JLabel("습도"); JLabel rehlbl2 = new JLabel(s.hum); t1hlbl.setBounds(10, 350, 150, 50); t1hlbl2.setBounds(60, 350, 150,50); data_p.add(t1hlbl); data_p.add(t1hlbl2); rehlbl.setBounds(10, 400,150,50); rehlbl2.setBounds(60,400,150,50); data_p.add(rehlbl); data_p.add(rehlbl2); data_p.add(locationlbl); data_p.setSize(400,200); menu_frame.add(data_p); menu_frame.setSize(400,500); menu_frame.setVisible(true); menu_frame.addWindowListener(new WindowListener() { @Override public void windowClosed(WindowEvent e) { } @Override public void windowOpened(WindowEvent e) { } @Override public void windowClosing(WindowEvent e) { //String date Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyMMddhhmm"); out.println("LOGOUT"+ sdf.format(date)); } @Override public void windowIconified(WindowEvent e) { } @Override public void windowDeiconified(WindowEvent e) { } @Override public void windowActivated(WindowEvent e) { } @Override public void windowDeactivated(WindowEvent e) { } }); add_friend.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new Addfr(); } }); change_info.addActionListener(new ActionListener() { // 메뉴에서 정보변경 버튼 누르면 @Override public void actionPerformed(ActionEvent e) { new ChangeInfo(); } }); } } public class Invite //로그인해서, user를 검색하는창 { public Invite(String id) { JFrame iadder=new JFrame(); iadder.setTitle("초대하실 id를 입력해주세요."); iadder.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); iadder.setLayout(new FlowLayout()); JLabel inviid=new JLabel("아이디"); JTextField iid=new JTextField(20); iadder.add(inviid); iadder.add(iid); iadder.setSize(300,150); iadder.setVisible(true); JButton invitefr=new JButton("초대"); JPanel pnr=new JPanel(); pnr.add(invitefr); iadder.add(pnr,BorderLayout.SOUTH); invitefr.addActionListener(new ActionListener() //text로 정보를 확인하고, 친구를 추가함. { public void actionPerformed(ActionEvent e) { String comment=e.getActionCommand(); if(comment.contentEquals("초대")) { String inviname=iid.getText(); //텍스트창에서 문서를 받아온다 out.println("Invite"+inviname+":"+id); iadder.dispose(); } } }); } } public class Addfr //로그인해서, user를 검색하는창 { public Addfr() { JFrame adder=new JFrame(); adder.setTitle("친구 검색"); adder.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); adder.setLayout(new FlowLayout()); JLabel searid=new JLabel("아이디"); JTextField uid=new JTextField(20); adder.add(searid); adder.add(uid); adder.setSize(300,150); adder.setVisible(true); JButton search=new JButton("검색"); JButton add=new JButton("추가"); JButton list=new JButton("친구리스트"); JPanel pnr=new JPanel(); pnr.add(search); pnr.add(add); pnr.add(list); adder.add(pnr,BorderLayout.SOUTH); search.addActionListener(new ActionListener() //text를 작성하고, 검색을 함. { public void actionPerformed(ActionEvent e) { String comment=e.getActionCommand(); if(comment.contentEquals("검색")) { String conveyid=uid.getText(); //텍스트창에서 문서를 받아온다 out.println("Search"+conveyid);//서버에 검색하는 아이디를 전달. } } }); add.addActionListener(new ActionListener() //text로 정보를 확인하고, 친구를 추가함. { public void actionPerformed(ActionEvent e) { String comment=e.getActionCommand(); if(comment.contentEquals("추가")) { relaid=uid.getText(); //텍스트창에서 문서를 받아온다 out.println("ADDF"+relaid);//서버에 추가하려는 id를 보낸다. } } }); list.addActionListener(new ActionListener() //text로 정보를 확인하고, 친구를 추가함. { public void actionPerformed(ActionEvent e) { String comment=e.getActionCommand(); if(comment.contentEquals("친구리스트")) { out.println("List"+curid); } } }); } } public class ChangeInfo{ //내정보 변경하는 창 public ChangeInfo() { JFrame ch_frame=new JFrame(); JPanel ch_panel = new JPanel(); ch_panel.setLayout(null); ch_frame.setTitle("내 정보 변경"); JLabel nicklbl2 = new JLabel( "Nick Name"); JTextField nickField2 = new JTextField(50); //바꿀 닉네임 JLabel commentlbl = new JLabel("Comment"); JTextField commentField = new JTextField(50); // 바꿀 상태 메시지 JButton ch_btn = new JButton("정보 변경"); // 정보 변경 버튼 누르면 바꾸고자 하는 정보가 반영됨 nicklbl2.setBounds(10,10,100,30); nickField2.setBounds(130, 10, 300,30); ch_panel.add(nickField2); ch_panel.add(nicklbl2); commentlbl.setBounds(10,80,100,30); commentField.setBounds(130, 80, 300,30); ch_panel.add(commentlbl); ch_panel.add(commentField); ch_btn.setBounds(330,120,100,30); ch_panel.add(ch_btn); ch_frame.add(ch_panel); ch_frame.setSize(500,200); ch_frame.setVisible(true); ch_btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String ch_nick = nickField2.getText(); String ch_comment = commentField.getText(); out.println("ChangeInfo:"+ch_nick+":"+ch_comment); // 바꿀 내용 서버에 알림 user_state.setText(ch_comment); // 바꾼 내용을 메뉴 칸에 반영함 ch_frame.dispose(); } }); } } private void run() { try { Socket socket = new Socket(serverAddress, portnum); //입력받은 ip주소와 portnumber로 소켓 생성. in = new Scanner(socket.getInputStream()); out = new PrintWriter(socket.getOutputStream(), true); String[] userinfo = null; while(true) { String line=in.nextLine(); System.out.println(line); if(line.contains("access")) { userinfo = line.split(":"); JOptionPane.showMessageDialog(null, "로그인 성공", "로그인 확인!", JOptionPane.DEFAULT_OPTION);//서버가 로그인 성공이라고 했을 시, 창 표출 //TODO: new Menu(userinfo[1],userinfo[2],userinfo[4]); curid=userinfo[3]; } // 아이디가 틀렸을 때 else if(line.contains("id invalid")) { JOptionPane.showMessageDialog(null, "아이디 틀림!", "로그인 확인!", JOptionPane.DEFAULT_OPTION); //로그인 실패 시, 창표출 return; } // 비밀번호가 틀렸을 때 else if(line.contains("pw invalid")) { JOptionPane.showMessageDialog(null, "비밀번호 틀림!", "로그인 확인!", JOptionPane.DEFAULT_OPTION); //로그인 실패 시, 창표출 return; } else if(line.contains("Welcome")) { JOptionPane.showMessageDialog(null, "회원가입성공", "환영합니다!", JOptionPane.DEFAULT_OPTION); //회원가입 성공 시, 창표출 return; } else if(line.contains("Searching")) //검색한 정보를 받았을 때, { String printinfo=line.substring(9); //정보 뽑아냄 String [] showbox=printinfo.split(" "); String wholeinfo=""; wholeinfo="name"+":"+showbox[0]+"\n"+"birthday"+":"+showbox[1]+"\n"+"email"+":"+showbox[2]+"\n"+"comment"+":"+showbox[3]; JOptionPane.showMessageDialog(null, wholeinfo, "검색하신 정보는 위와 같습니다.", JOptionPane.DEFAULT_OPTION); //묶은 정보를 출력. } else if(line.contains("ADD")) //친구 추가완료됨 { JOptionPane.showMessageDialog(null, "친구추가완료", "축하합니다", JOptionPane.DEFAULT_OPTION); //친구추가된 경우, 창표출 friend_model.addElement(relaid); } else if(line.contains("DUPLICATION")) { JOptionPane.showMessageDialog(null, "이미 추가된 친구입니다.", "친구 추가 실패",JOptionPane.DEFAULT_OPTION);// 친구가 중복된 경우 } else if(line.contains("Frlist")) //server가 친구리스트를 보내줬을 때. { String flend=line.substring(6); //친구리스트를 문자열화 String [] flist=flend.split(" "); //친구리스트가 한꺼번에 왔기 때문에, 쪼개준다. String ourfr=""; for(int i=0; i<flist.length;i++) { ourfr=ourfr+flist[i]+"\n"; //ourfr에 친구리스트 쪼개서 저장 } JOptionPane.showMessageDialog(null, ourfr, "고객님의 친구명단은 아래와 같습니다", JOptionPane.DEFAULT_OPTION); //친구명단을 임시로 창표출 return; //친구리스트 출력. } else if(line.contains("No user")) //server에서, 해당 사용자가 없다고 왓을 경우 오류 출력. { JOptionPane.showMessageDialog(null, "존재하지 않는 아이디입니다.", "error ", JOptionPane.DEFAULT_OPTION); //친구명단을 임시로 창표출 } else if(line.contains("Message")) { sendTF.setEditable(true); String msg = line.substring(7); ta.append(msg + "\n"); } else if(line.contains("Request")) { String ifo=line.substring(8); String [] temp=ifo.split(":"); String rcv=temp[0]; String snd=temp[1]; if(rcv.equalsIgnoreCase(curid)==true) { int result=JOptionPane.showConfirmDialog(null, snd+"으로부터 요청이 왔습니다", "confirm", JOptionPane.YES_NO_OPTION); if(result == JOptionPane.NO_OPTION) { out.println("Nop"+snd+" "+"reject the chatting"); } else if(result == JOptionPane.YES_OPTION) { new Chatting_Room(rcv); out.println("Join"+rcv); } } } else if(line.startsWith("Invite")) { String [] tmp=line.split(":"); System.out.println(tmp[1]); System.out.println(curid); if(curid.equalsIgnoreCase(tmp[1])==true) { int result2=JOptionPane.showConfirmDialog(null, tmp[2]+"으로부터 요청이 왔습니다", "confirm", JOptionPane.YES_NO_OPTION); if(result2 == JOptionPane.NO_OPTION) { out.println("Nop"+tmp[2]+" "+"reject the chatting"); } else if(result2 == JOptionPane.YES_OPTION) { new Chatting_Room(tmp[1]); out.println("Join"+tmp[1]); } } } else if(line.contains("Denied")) { ta.append(line.substring(6)); } } } catch(Exception e) { System.out.println(e); } finally { frame.dispose(); } } public static void server(String fileName) //input.txt파일에서 ip주소와 port number를 불러오는 함수. { Scanner inputStream = null; try { inputStream = new Scanner(new File(fileName));//input파일을 읽어옴. } catch (FileNotFoundException e) //파일이 없을 경우, 자동생성 { ip = "localhost"; portnum = 9999; e.printStackTrace(); } while (inputStream.hasNext()) //input파일에서, ip주소와 portnumber를 읽어옴. { ip = inputStream.next(); portnum = inputStream.nextInt(); } } public static void main(String args[]) { String fname="input.txt"; server(fname); // input내용으로 정보 불러오기 Login client=new Login(ip); client.run(); } }
Forums:
댓글 달기