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

httpclient 이 문제가 과연 풀릴 수 있는 지 의문입니다.

0 추천

안녕하세요,

DefaultHttpClient 를 이용해서, 서버와 통신하는 앱을 만들었습니다.

그런데, 이게 재미있는 현상이 있습니다.

가끔 통신이 되지 않는 건데요,

공유기 상태에서 여러가지 device를 물려 놓으면 안드로이드만 문제가 있습니다. 

같은 서버로 아이폰, 안드로이드, pc 브라우저 3개를 이용해서 접속해 보면

pc브라우저와 아이폰은 동시에 아주 잘 접속되는데,

안드로이드는 다른 것들과 동시에 접속을 시도하면 안됩니다.

미치고 팔짝 뛰겠습니다. 한번 안되면 20초~1분 정도는 접속이 안됩니다. 

어느 정도 시간이 지나면 정상적으로 접속되나, 또 동시에 시도하면 박살 납니다. 

 

일단,  코드와 로그를 보면 재미있습니다.  (사실 코드는 재미없고, 로그는 재미있습니다.)

(thread에서 접속부 구현이고요, 필요한 부분만.)

private HttpClient getHttpClient() {
		
        HttpClient httpClient = null;
        try {
            final HttpParams params = new BasicHttpParams();
 
            // PARAMS
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
            HttpConnectionParams.setConnectionTimeout(params, 1000 * 20); // 30s timeout.
            HttpConnectionParams.setSoTimeout(params, 1000 * 20); // 30s timeout.
            HttpConnectionParams.setSocketBufferSize(params, 512 * 1024);
            HttpConnectionParams.setStaleCheckingEnabled(params, false);
            HttpClientParams.setRedirecting(params, false);
              params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
 
            // SCHEME
            final SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
 
            final ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
            
            httpClient = new DefaultHttpClient(ccm, params);
             
        } catch (Exception e) {
			e.printStackTrace();
            httpClient = new DefaultHttpClient();
        }
          return httpClient;
    }


위 부분이 httpclient를 만드는 부분이고요, (참고로 서버는 keepalive off입니다)

 

String url = common.URL_CHECK;
				
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
HttpPost httpPost = new HttpPost(url);
UrlEncodedFormEntity entityRequest = new UrlEncodedFormEntity(params, "UTF-8");
httpPost.setEntity(entityRequest);
HttpClient http =getHttpClient();
HttpResponse httpResponse = http.execute(httpPost);
HttpEntity entity = httpResponse.getEntity();
InputStream inStream = entity.getContent();
	
...............

요 부분이 실제 thread에서 통신하는 부분입니다. 

 

이제 재미있는 로그를 볼 차례인데요, 

로그는 제가 http packet generation까지 로그를 찍었으니까 재미있습니다(?)

첫번째는  될 때의 로그 입니다. 

11-11 15:49:59.449: D/libc(24344): DNS query requested to DNS proxy daemon hostname = xxxx.com 
11-11 15:49:59.449: D/libc(24344): getaddrinfo proxy result code is = 222
11-11 15:49:59.449: D/libc(24344): getaddrinfo DNS proxy process success
11-11 15:49:59.479: D/org.apache.http.wire(24344): >> "POST /check.php HTTP/1.1[EOL]"
11-11 15:49:59.479: D/org.apache.http.wire(24344): >> "Content-Length: 0[EOL]"
11-11 15:49:59.479: D/org.apache.http.wire(24344): >> "Content-Type: application/x-www-form-urlencoded[EOL]"
11-11 15:49:59.479: D/org.apache.http.wire(24344): >> "Host: xxxxx.com[EOL]"
11-11 15:49:59.479: D/org.apache.http.wire(24344): >> "Connection: Keep-Alive[EOL]"

.............. (로그가 길어서 질문이 안올라가니까 생략)

11-11 15:49:59.600: D/org.apache.http.wire(24344): << "[{"success":true,"message":"wow","count":123}][\n]"

딱 보시면 아시겠지만,

될 때는 http.execute(httpPost) 를 하자마자 제대로 http packet을 만들어서 결과 200까지 받아오는 정상적인 코스를 밟죠. 열심히 handshake까지 열심히 합니다~!

그런데! 안될 때는 

11-11 15:51:23.219: D/device(24344): 1080, 1920
11-11 18:16:47.318: D/matching_count(15086): org.apache.http.impl.client.DefaultHttpClient@43007968

11-11 15:51:23.219: D/matching_count(24344): after getHttpClient
11-11 15:51:23.229: D/libc(24344): DNS query requested to DNS proxy daemon hostname = xxxxx.com 
11-11 15:51:23.229: D/libc(24344): getaddrinfo proxy result code is = 222
11-11 15:51:23.229: D/libc(24344): getaddrinfo DNS proxy process success


<----------- 바로 여기에서 패킷이 만들어져야 되는데 .... --------->

11-11 15:51:43.240: W/System.err(24344): org.apache.http.conn.ConnectTimeoutException: Connect to /11.11.11.1 timed out
11-11 15:51:43.240: W/System.err(24344): 	at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121)
11-11 15:51:43.240: W/System.err(24344): 	at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
11-11 15:51:43.250: W/System.err(24344): 	at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
11-11 15:51:43.250: W/System.err(24344): 	at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
....................... 중간 생략 .....................
11-11 15:51:43.260: W/System.err(24344): 	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)

딱 이상하게 보이죠. execute를 했는데, paket을 만들지 않고,  멍 때리다가 일정 시간이 지나니까 timeout이 걸려 버립니다. 

실제로 서버의 access_log를 살펴보면 access를 시도한 적이 없습니다. 

그래서 중간에 debug로 혹시 defaultHttpClient가 null인가 싶어서 debugging log 찍어 보니 그것도 아닙니다. 뭔가 주소를 가져오긴 하는데, execute할 때 packet을 만들지 않고, 쐈다고 생각하는 것 같습니다.

 

이것을 어쩌면 좋을까요? 

인류 최대의 숙제일까요, 아니면 죽을 때 까지 그냥 가져가야 할 버그일까요. 

제가 무엇을 잘못하고 있는 걸까요?

 

해결 될 수 있는 조언을 해 주신 분께는 

소개팅을... 할 수 있도록 노력해 보겠습니다. 와하하! (살려주세요)

 

아이구 머리야. 

아이갓씨 (140 포인트) 님이 2013년 11월 12일 질문
...'공유기 상태에서 여러가지 device를 물려 놓으면'..

공유기를 최신 걸로 교체해보세요.
-,.- 크흑.. 상황을 새롭게 보는 능력!
농담처럼 들릴지 모르지만, 그렇지도 않습니다.

과거 공유기의 경우 무선으로 일정수 이상이 붙었을때 기기들의  접속이 끊어지거나 네트웍 속도 저하가 있었습니다. 그러니까 애초 설계때 무선 노트북이 붙을걸 전재해서 1~2대 정도의 허용량만이 있었던거지요.

그래서 1년 전 정도부터 출시된 공유기들은 높은 처리량으로 '모바일에 최적화 되었다.' 라고 홍보합니다. 만약 해당 상황이 다른곳에서 동일하게 재현되는지 확인해보세요.
넵!! 감사합니다.

그런데, 재미있는 건, 어쨌거나,
iOS나 브라우저에는 절대 나오지 않는 현상이라는 게
아주아주 마음에 걸립니다. -,.-;;
(다른 공유기에서도 그렇고, 음.
 제가 테스트 중인 공유기는 iptime N6004R 로 작년 모델이에요 ㅠㅠ)

같이 붙이면 iOS나 노트북 브라우저는 전혀 문제가 없고
안드로이드만 그래요. ㅠㅠ
예 저도 공유기 바꾸기 전까지 안드로이드만 이러는 현상이 있었습니다.
그래서 안드로이드의 벤더쪽(휴대폰 제작사) wifi 처리가 좀 부실하구나 정도의 추정만 할수 있었습니다.

하지만 N604R 정도면 이런 문제 없을것 같은데, 해당 폰의 문제일것 같네요.
넵! 알겠습니다!!
다른 공유기에서도 테스팅해보겠습니다~~~!!!!

2개의 답변

+1 추천

저랑은 약간 다른경우인거같은데 저같은경우는 iis서버와 통신할때 문제가 있었습니다.

기기자체 브라우저에서 파일다운로드를 클릭했을때도 프리징이 있고 일정시간뒤에 타임아웃이 되는 현상이었는데 os를 수정할수 있는게 아니니 별수없이 톰캣으로 우회했었습니다.

http://www.androidpub.com/index.php?mid=android_dev_info&document_srl=2557027

냉동참치 (2,340 포인트) 님이 2013년 11월 12일 답변
안녕하세요~! 감사합니다.

일단 저는 오늘은 공유기에 실제 패킷이 도달하는가!
공유기에서 패킷은 나가는가! 를 확인해 볼까 합니다!!! 크흐흐흑.
+1 추천
저도 예전에 같은 경험이 있는데요

그냥 서버 문제였습니다. 혹시 웹호스팅 쓰시면 다른 종류의 호스팅으로 바꿔보시기 바랍니다.
Gradler (109,780 포인트) 님이 2013년 11월 12일 답변
감사합니다!

그런데, 웹호스팅은 아니고 카페24 서버 호스팅을 사용하고 있는데요,
로그를 보면 아예 packet을 만들지 못하고 있는데
서버 문제 일까요?

혹시 어디 호스팅 쓰셨었어요~?
저도 cafe 24 였습니다.
서버 설정을 마구마구 헤쳐보겠습니다!!!
...