424
408
2020-01-31 14:08:42 작성 2020-02-05 09:33:04 수정됨
18
719

자바 TCP/IP 멀티쓰레드 클라이언트부분 질문드립니다.



0
0
  • 답변 18

  • 죠낸또이또이
    2020-01-31 14:46:42

    오픈 되었을때랑 송수신할때 쓰레드 NAME값이 달라가지고요(증가가됩니다..)

    - Client의 Thread Name이랑 Server의 Thread Name이랑 비교하신건가요?


    0
  • 죠낸또이또이
    2020-01-31 15:13:48

    public void tcp_open() { // TCP/IP 오픈

    try {

    sock = new Socket("127.0.0.1", 12000); // 서버로 접속

    th = new Thread();

    System.out.println("쓰래드생성 " + th.getName());


    } catch (IOException e) {

    System.out.print("IOException\n");

    }

    }


    public String tcp_message(InputStream msg) { // TCP/IP 메시지 송수신

    try {

    FormatString fs = new FormatString();

    in = new DataInputStream(sock.getInputStream());

    in2 = new BufferedReader(new InputStreamReader(msg));

    out = new DataOutputStream(sock.getOutputStream());

    br = new BufferedReader(new InputStreamReader(sock.getInputStream()));


    String data = in2.readLine();


    // 서버로 문자열 전송

    out.writeUTF(fs.FormatStringnull(data, 1234));


    th = new Send10(out, in2);

    th.start();

    } catch (IOException e) {

    System.out.print("IOException\n");

    }


    try { // 클라이언트의 메인 쓰레드는 서버로부터 데이터 읽어들이는 것만 반복.

    while (true) {

    String str2 = in.readUTF();

    System.out.println("서버로부터 응답 -> " + str2);

    }

    } catch (IOException e) {

    }


    return thName;

    }




    오픈 되었을때랑 송수신할때 쓰레드 NAME값이 달라가지고요

    - 오픈했을 때 Thread는 객체만 생성하고 아예 사용을 안하고 계셔요.

    - tcp_message() 메서드에서는 새로운 Thread를 생성하고 있구요.

    이게 다르다는 말씀이 맞다면 다른게 정상이지요.


    그리고, 보니까 tcp_message 에서 송수신을 다 하고 계시는데

    수신 Thread와 송신 Thread를 별도로 만드시는게 좋아요.


    채팅을 구현하시면서 몇일동안 막히시는거같은데.. 흠... 인터넷에 소스하나 받으셔서 그것이 어케 동작되나 먼저 확인해보시고 그 다음 안보고 코딩해보시는게 나으실 것 같아요.


    https://blog.naver.com/regenea8/221442734125


    이건 제가 간단히 만들었던건데요. 여기서 클라이언트 부분 참고해보세요.



    0
  • 424
    408
    2020-01-31 15:22:13

    제가 위에서 말한대로 구현을 하려면 어떻게하는게 좋을까요?? ㅠㅠ 조언좀 얻을수있을까요??

    그리고 친절한 답변 정말 감사합니다!!

    0
  • 죠낸또이또이
    2020-01-31 16:32:12

    Main 함수는 어떻게 짜셨어요?


    0
  • 424
    408
    2020-01-31 16:39:20 작성 2020-01-31 16:40:05 수정됨

    main은 따로없구 WEBSocket이랑 연동해서 하고있거든여 ㅠㅠ

    웹소켓이 띄워지면 tcp/ip가 연결되고 웹소켓연동되면 tcp/ip로 데이터주고받고 그런식으로 하고있어요..ㅠㅠ

    그리고 송신은 그냥 쓰레드로 안하고 무한루프로 서버에서 받으면 되거든요! ㅠ

    // 웹 소켓이 연결되면 호출되는 이벤트

    @OnOpen

    public void onOpen(Session session) {

    nickname = GUEST_PREFIX + connectionIds.getAndIncrement();

    sessionMap.put(nickname, session);

    String message = String.format("* %s %s", nickname, " 접속");

    tic.tcp_open();

    }


    @OnMessage

    public void onMessage(String message, Session session) {

        InputStream iomsg = new ByteArrayInputStream(message.getBytes());

    tic.tcp_message(iomsg);

    if (null == iomsg && "".equals(iomsg))

    return;

    String filteredMessage = String.format("%s: %s", nickname, iomsg);

    if (this.nickname.equals("손님0")) {

    sendToOne(message, sessionMap.get("손님0"));

    }else if(this.nickname.equals("손님1")) {

    sendToOne(message, sessionMap.get("손님1"));

    }

    }

    0
  • 424
    408
    2020-01-31 16:42:02

    핵심은..

    OPEN할때의 쓰레드네임을 가지고 송수신할때 오픈되었을때에 해당하는 쓰레드네임을가지고 송수신하게 하고싶은데 송신할때마다 계속 쓰레드네임이 증가하네요..ㅋㅋㅋ  

    이거입니다 ㅠㅠ

    0
  • 죠낸또이또이
    2020-02-03 09:47:37

    음.. 저는 웹 소켓을 사용해본적이 없어서 잘 모르지만..


    1. Send10 생성자를 없애시고 빈 깡통으로 onOpen 에서 오픈하시구요.

    2. onMessage 에서 setter로 Send10 안에 stream 을 아규먼트로 넘겨주시면 될 것 같네요.


    0
  • 424
    408
    2020-02-03 11:18:52

    노란색줄처럼 저렇게 오픈시켜주면 될까여?


    Thread th = null;


    public void tcp_open() { // TCP/IP 오픈

    try {

    sock = new Socket("127.0.0.1", 12000); // 서버로 접속

    th = new Send10();

    th.start();

    } catch (IOException e) {

    System.out.print("IOException\n");

    }

    }

    0
  • 죠낸또이또이
    2020-02-03 11:26:12
    네 그리고 onMessage 에서는 new Sned10을 하지 않고 setter로 out과 in넘겨보세요.
    0
  • 죠낸또이또이
    2020-02-03 12:23:08

    public String tcp_message(InputStream msg) { // TCP/IP 메시지 송수신

    try {

    FormatString fs = new FormatString();

    in = new DataInputStream(sock.getInputStream());

    in2 = new BufferedReader(new InputStreamReader(msg));

    out = new DataOutputStream(sock.getOutputStream());

    br = new BufferedReader(new InputStreamReader(sock.getInputStream()));


    String data = in2.readLine();


    // 서버로 문자열 전송

    out.writeUTF(fs.FormatStringnull(data, 1234));


    th = new Send10(out, in2);

    th.start();

    } catch (IOException e) {

    System.out.print("IOException\n");

    }


    try { // 클라이언트의 메인 쓰레드는 서버로부터 데이터 읽어들이는 것만 반복.

    while (true) {

    String str2 = in.readUTF();

    System.out.println("서버로부터 응답 -> " + str2);

    }

    } catch (IOException e) {

    }

    return thName;

    }

    }




    색칠된 부분을 th.setOut(out);, th.setIn2(in2); 로 넘기라는 말씀입니다.

    혹시 setter 와 getter는 아시는지요?

    0
  • 죠낸또이또이
    2020-02-03 12:51:55

    아뇨 Send10 클래스에서는 getter 할 필욘 없습니다.

    전역 변수로 되어 있으니 내부에선 그냥 사용할 수 있죠.

    0
  • 죠낸또이또이
    2020-02-03 20:00:42

    start는 Open 할 때 했으니 이미 한거구요.

    메시지를 받으면 이전 소스에 new Send 하시길래 그걸 변경해드린게 전부입니다.


    다시 말씀드리지만 저도 웹 소켓은 사용해보지 않아서 어떻게 연결해야하는지는 몰라요.

    단순히 Thread를 2번 생성하신걸 한번으로 정정해드린게 전부입니다.


    0
  • 죠낸또이또이
    2020-02-03 20:03:50

    이제 Thread는 1회만 생성(new Send10) 후 실행(th.start)하니

    thread.name이 계속 증가할 일은 없을 것 입니다.


    다만, open할 때 socket을 생성하시는데, 그걸 new Send10할 때 넘겨줘야 할 것 같은데

    웹 소켓을 사용해보지 않아서 안넘겨도 되는질 모르겠네요.

    (@OnMessage public void onMessage(String message, Session session) 메서드가 메시지가 수신됐을 때 받는 것 같은데 내부적으로 어떻게 돌아가는질 모르니..)



    0
  • 424
    408
    2020-02-04 15:46:36

    아하 어느정도 해결했습니다 감사합니다!!!!!

    0
  • 424
    408
    2020-02-04 16:40:47

    근데 쓰레드네임 반환하면 왜Thread-3부터시작하고 2씩증가를할까여..?

    0
  • 죠낸또이또이
    2020-02-04 18:16:32
    위 코드대로 진행해도 그렇게 나오나요?
    0
  • 424
    408
    2020-02-05 09:28:21
    네네 ㅠㅠ
    0
  • 죠낸또이또이
    2020-02-05 09:34:00

    웹 소켓이랑 연동하면서 뭐가 있나.. Thread Name은 크게 신경쓰지 마세요 ㅎㅎ

    API 에 보면 아마도 Thread Name 을 자유 자제로 변경하는 함수도 있을 겁니다.

    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.