java socket프로그래밍 관련 질문입니다.

ehyuck의 이미지

소켓 프로그래밍 관련 질문입니다. 멀티쓰레드 환경으로 여러개의 채팅방을 구현하려는 코드를 작성중입니다.
그래서 제가 구현한 방식은 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();
    }
}

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.