마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드 소켓 통신 제발 도와주세요

0 추천

안녕하세요. 이번에 서버쪽이랑 같이 공부하려고 소켓 통신 에제를 실행해보려고 했는데

인터넷에 있는 코드들을 10개는 넘게 작성해 본 것 같은데 전혀 안되서 2일째 골치아픈 상황입니다.

일단 상황은 안드로이드에서 Socket을 사용해서 nodejs서버와 소켓을 연결하는데, 코드는 아래처럼 작성했습니다.

package com.example.myapplication

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import io.socket.client.IO
import io.socket.client.Socket
import io.socket.emitter.Emitter
import java.net.URISyntaxException

class MainActivity : AppCompatActivity() {
    lateinit var mSocket: Socket
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        try{
            mSocket = IO.socket("http://192.168.XXX.XXX:3000")
            mSocket.connect()
            Log.d("test", "socket.io connected !!");
        }catch(e: URISyntaxException){
            Log.e("MainActivity", e.reason)
        }
        mSocket.on(Socket.EVENT_CONNECT, onConnect);
    }
    val onConnect = Emitter.Listener {
        Log.d("TAG", "connect!")
    }

}
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);

app.get('/', (req, res) => {
  console.log("user connect22");
  res.send({"result":"hello"});
});

io.on('connection', function(socket) {
  console.log("user connect");

});

server.listen(3000, function(){
  console.log("server on 3000");
});

테스트를 위해서 최대한 간단하게 작성했습니다.

클라이언트에서 try블록 내의 Log는 정상적으로 찍히는걸 확인했습니다.

그런데 서버 쪽에서 io.on내부의 콘솔 로그가 찍히지 않는 걸 보니 정상적으로 연결이 안된 것 같습니다.

확인해본 해결 방법은

1. manifest에 INTERNET권한 추가.

2. manifest에 android:usesCleartextTraffic="true"추가

3. 포트 포워딩, 방화벽 해제

4. 주소 공인IP로 변경(127.XXX.XXX.XXX)

5. 서비스쪽으로 코드 옮겨서 코루틴으로 실행

retrofit을 사용해서 서버에 get요청을 보내면 정상적으로 request가 오는건 확인했는데 

소켓 통신만 안되는 상황입니다..

코드도 인터넷에서 찾아서 10번은 넘게 바꿔본 것 같은데 아무리 해도 안되네요ㅠ

*오타 수정했습니다.(해결안됨)

*공인IP로 모바일에서 접속하니까 정상적으로 연결됐습니다!

 전에 로컬에서는 안된다고 하는 글을 본 적이 있는데...

*안드로이드 스튜디오에서 ADV로 실행해도 정상 작동하네요..?

 스튜디오를 재설치 해서 그런가, 아니면 그 외에 몇 가지 했던 것 덕분에 해결 된 건가 잘 모르겠네요;

 3일간 고생은 대체 뭐였는지 ㅠㅠ

bonon (620 포인트) 님이 2021년 2월 5일 질문
bonon님이 2021년 2월 5일 수정
htpt:// 이건 오타인가요?
아 코드를 계속 바꾸다보니 오타낫나봅니다.
이전에 http로 했을때도 안되는거 확인했습니다..
좀 이상한게 소켙통신을 하는데 tcp/ip가 아니라 왜 http 프로토콜을 사용하나요? 이 경우는 클라이언트에서 http 프로토콜을 구현주셔야 하는데...
안드로이드에서 socket.io모듈 사용해서 통신합니다!
상황을 보면 서버는 확실히 클라이언트들을 리슨하고 있고 커넥션도 가능한 상황인데 안드로이드 클라이언트만 안된다는 건데요. 현재 서버는 http 프로토콜을 구현하고 있고 테스트하신 nodejs도 http를 클라이언트 인거 같은데. 웹브라우져도 기본이 http 프로토콜이구요. http  클라이언트들과 통신할 때  문제가 없다는 건 확인이 됐구요.
현재 안드로이드 앱은 tcp/ip를 쓰는 걸로 보이는데, 서버는 http라서 거기에 따른 프로토콜 문제가 아닌가 추측했거든요.  Retrofit으로 된다면 그건 안드로이 클라이언트가 http로 통신하는데 전혀 문제가 없다는 말입니다. 서버와 클라이언트간에 프로토콜이 틀리면 접속은 되더라도 바로 끊겨 버리게 될 겁니다. 왜냐하면 프로토콜 상에 서로 주고 받아야 하는 데이터들이 존재하는데 tcp/ip raw socket을 사용하게 되면 이 부분은 자동으로 해주지 않기 때문에 서버와의 통신이 더 진행될 수 없습니다. 노드 서버도 tcp/ip 서버를 돌려서 테스트 해보세요. 아니면 자바로된 서버 소켙 예제를 사용하셔도 돼구요.

1개의 답변

+1 추천
크롬이나 아무 웹브라우저를 띄워서
192.168.xxx.xxx:3000
이렇게 입력하면 뭐라고 나오나요?

웹브라우저에서 접속 안되면, 안드로이드의 문제가 아닙니다.

또 하나의 가능성은,

공유기 안쪽에서는 공인IP로 하면 밖으로 나가는데,
공유기가 저렴한 거면, 다시 안으로 못들어옵니다.

환경적인 문제일 것으로 보입니다.
Will Kim (43,170 포인트) 님이 2021년 2월 5일 답변
사설IP, 공인IP로 서버PC에서 접속 되는거 확인헀고,
와이파이 끄고 LTE로 핸드폰에서 웹접속 되는것도 확인했습니다.
후자는 무슨 말씀이신지 잘 이해가 안되네요 ㅠ

-nodejs로만 클라이언트, 서버파일 작성해서 시험해보니
이때는 socket통신이 잘 작동하네요.. 왜이러는걸까요
LTE로 해당 휴대폰에서 휴대폰 브라우저로 접근했을 때는 된다면,
서버는 정상적으로 보이네요.
그렇다면 후자는 신경 안써도 될 것 같네요.

아래 부분이 의심이 좀 되네요.

var server = require('http').createServer(app);

다른 샘플들도 시도해 보세요.
...