자바 awt채팅 몇일째해도 안되네요ㅠㅠ 제발 해결방법좀ㅠㅠ
서버는 바로 채팅창 띄워서 클라이언트 접속할때 기다리고요
클라이언트는 로그인 프레임창을 띄운다음 거기에서 이름 입력하고 접속버튼 누르면
본격적인 채팅 프레임이 화면에 띄워집니다. 로그인 창은 없어지고요. 근데 클라이언트 채팅창이 멈춰요ㅠ
클라이언트 채팅 프레임이 TextField, TextArea, 버튼은 띄워졌는데 그림도 안띄어지고
작동을 안합니다; 아예 멈춰요.
버튼 눌러도 아무 반응 없고
그런데 서버에서 종료버튼 눌러서 꺼버리면
그제서야 클라이언트에서 아무 반응 없다가 버튼 눌러진게 실행이 되고요;;
왜이러죠?;;
로그인과 클라이언트 채팅 창은 파일 2개로 따로 만들었고요.
(클라이언트 채팅 클래스 먼저 컴파일, 실행한 뒤 로그인 컴파일하고 실행)
로그인=========
...
버튼 이벤트처리
textarea.append("서버소켓과의 연결을 시도합니다.\n");
public void actionPerformed(ActionEvent ae) {
Client client = new Client();
String a = tf_name.getText(); // 텍스트 객체를 스트링으로 변환(tf_name->a)
if(tf_name.getText() != null) {
Client_awt.socket = new Socket("localhost", 7777);
try
{
client.a(tf_name.getText()); //클라이언트(채팅) 클래스 a메소드 호출
dispose(); //로그인창 닫음
}
catch (NullPointerException ne)
{
System.out.println("예외발생");
}
..
채팅 프로그램은 ====================
public class Client extends Frame{
private static TextArea sView = new TextArea("", 3, 60);
private static TextArea mView = new TextArea("", 8, 60);
private static TextField sendBox = new TextField("메시지를 입력", 54);
private static TextField id = new TextField("대화명]", 48);
private static Button b1 = new Button("스크린 클린");
private static Button b2 = new Button("종료");
...
void a(String a){
..
this.add(sView);
this.add(mView);
this.add(id);
this.add(b1);
this.add(sendBox);
this.add(b2);
..
setSize(500,700);
setVisible(true);
b2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
try{
System.exit(0);
}catch(Exception e){}
}
});
sendBox.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
try{
name1 = id.getText();
str1 = sendBox.getText();
mView.append(name1 + " : " +str1);
mView.append("\n");
dos.writeUTF(name1);
dos.writeUTF(str1);
sendBox.setText("");
}catch(Exception e){}
}
});
connect(); //connect호출 (채팅대화할수 있는 함수)
}//a
void connect(){
try{
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
while(true){
name2=dis.readUTF();
str2=dis.readUTF();
mView.append(name2 + " : " + str2 +"\n");
}
}catch(Exception e){}
}
}
1. 서버 실행하고
2. 클라이언트 실행
클라이언트 로그인 버튼 누르고나면
서버창에는 클라이언트 접속했다고 뜹니다; 하지만 클라이언트 채팅창은 그대로 멈춰잇고요; 글씨도 안먹히고 버튼도 안돼요
근데 서버끄면 그제서야 됩니다;;ㅠㅠ
몇일째 계속 고민중인데 전혀 안풀려요ㅠ 정말 미치겠네요;
아마 크로스 스레드 문제 아닌가요?
코딩상 아무 문제가 없다고 생각이 드시면.. ㅋㅋ
awt로 gui 짜본적은 없지만..
C#이나.. SWT로 짰었는데.. 저도 이런 문제가 ㅋㅋ
저는 그 문제가 크로스 스레드 문제였는데... 이번것도 ㅋㅋ
크로스 스레드 문제일 가능성이 높네요 ^^;
C#은 델리게이트 SWT은.. excute??뭐시기 메소드가 있었는데 ㅋㅋ
여튼 아마 스레드 문제인 것 같습니다...
음 냐냐~
한참 쓰고나서
한참 쓰고나서 보니까 제가 소스 블럭을 잘못 읽은것 같네요... ㅋ
connect()함수를 호출하는 부분이 정확히 어디인지 알 수 있을까요?
-- Signature --
青い空大好き。
蒼井ソラもっと好き。
파란 하늘 너무 좋아.
아오이 소라 더좋아.
올려주신 소스
올려주신 소스 그대로라면 예외처리를 통과할 수도 있겠는데요?
connect 메소드에서 선언하지 않은 socket을 먼저 사용했어요.
이 메소드에서 예외처리를 해보세요. 서버단에서 주는 것도 없는데 받으려구해서 멈추는 경우일듯..
똑!똑!
똑!똑!
connect함수는 프레임
connect함수는 프레임 두번째(채팅 프레임) 만들고 끝에 바로 호출합니다ㅠ
이렇게 한번 해보심이...
connect를 별도의 Thread를 생성해서 호출해 보셨으면 합니다.
코드는 하도 오래전에라 정확하지 않을 수 있습니다만...
아래와 같이 호출하시면 될 듯 합니다.
단 connect안에서 초기화 하는 객체들에 대한 접근은 시간차에 따라 null이 될 수 있으므로 확실하게 보장할 수 없게 됩니다.
추가적인 처리가 필요할 수도 있습니다.
자바의 경우 모든 GUI 이벤트 처리가 멀티 쓰레드에 기반하기 때문에 new를 통해 GUI객체를 생성한다고 정상 작동을 보장할 수 없는걸로 알고 있습니다.
특히나 이벤트 리스너의 콜백 메서드 안에서의 처리는 지연되지 않는게 좋습니다.
-- Signature --
青い空大好き。
蒼井ソラもっと好き。
파란 하늘 너무 좋아.
아오이 소라 더좋아.
스윙에서 쓰레드 개념 부터 잡아 볼까요?
스윙에서 쓰레드 개념 부터 잡아 볼까요?
스윙에서 쓰레드를 분류하자면 3가지입니다.
1.메인
2.이벤트 디스펫쳐
3.워커
1.메인 : main()함수 실행될 때 생성됨 (모든 어플리 공통)
2.이벤트 디스펫치 쓰레드 : Frame이나 Window의 setVisible()이 호출 될 때 생성되어서 이벤트를 기다리고 엑션을 실행함
3.워커:오랜 시간일 걸리는 작업인 경우 2의디스펫쳐 쓰레드는 이 워커 쓰레드 생성하고 작업을 시키고 디스펫쳐 자신은은 리턴해서 화면 이벤트 처리를 계속합니다.
보통 1의 메인 쓰레드는 main()끝까지 실행하고 종료됩니다.
그 사이에 생성된 디스펫치 쓰레드가 남아 있기 때문에 프로그램 자체는 남아 있는 것이죠.
enjeli님의 예에서는 이 디스펫쳐가 데이터 입력을 기다리고 있기 때문에
화면처리가 일어나지 못하는 것입니다.
1.의 메인 쓰레드가 통신을 담당하고
2.의 디스펫쳐는 화면 처리만 하도록 하는 방법을 고려해 보세요.
메인 쓰레드는 javax.swing.SwingUtilities.invokeLater 등을 이용해서
디스펫치 쓰레드에게 화면 조작 관련 명령을 내릴 수 있습니다.
아마도...
쓰레드는 나중에 생각하고...
문제가 무엇인지를 파악하는게 중요합니다.
정말로 프로그램이 작동을 안하는건지 혹은...
작동은 하지만 창이 안움직이는 것처럼 보이는건지 확인해볼 필요가 있습니다.
일단 디자인을 짜봅시다.
로그인 -> 매인화면 -> 콘넥트
필요한것이 무엇인지 체크합니다.
하나의 프레임: 이것은 프로그램이 꺼질때까지 살아있을것입니다.
두개의 패널(View): 로그인 패널과 매인화면 패널이 있어야합니다.
하나의 콘트롤러(Controller): 액션리스너를 담당하는 콘트롤러입니다.
하나의 모델(Model): 로그인시 모델에서 정보를 받아 드립니다.
이 세개의 것을 하나로 만들어서 만드는 프로그램이라면 일단
JAVA MVC 를 살펴볼 필요가 있습니다.
몰라도 상관은 없지만 말이죠.
---------------------------------------------------------------------------------------------------------------
루비 온 레일즈로 만들고 있는 홈페이지 입니다.
http://jihwankim.co.nr
여러 프로그램 소스들이 있습니다.
필요하신분은 받아가세요.
댓글 달기