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

서버와 http통신을 하는데 자꾸 예외가 발생합니다.

0 추천
안녕하세요 제가 서버와 http통신을 하는데 자꾸 예외가 발생합니다. 10번하면 2~3번은 발생하는 에러라

조금 난감한데요. 제가 궁금한것이

1. http 연결을 할때 서버로부터 데이터를 받아들이지 못하는 경우 nullpointer exception

2. 서버로부터 데이터를 받으나 데이터가 짤리는 경우

3. socket exception 발생

4. 시간초과로 인한 connect Time 예외 발생

이렇게 예외처리가 발생하는데 httpcilent 가 원래 이렇게 요청하면 데이터 정확성이 낮은지 궁금합니다.!

안드로이드 소스
class LoadMachineSpec extends AsyncTask<Void, String, Void> {
 
    @Override
    protected Void doInBackground(Void... param) {
        try {
            HttpParams httpParameters = new BasicHttpParams();
            HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1);

            HttpClient client = new DefaultHttpClient(httpParameters);

            HttpConnectionParams.setConnectionTimeout(httpParameters, 2000);
            HttpConnectionParams.setSoTimeout(httpParameters, 2000);
            HttpConnectionParams.setTcpNoDelay(httpParameters, true);
            // 주소
            String postURL = "url;
            HttpPost post = new HttpPost(postURL);
            ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();

            params.add(new BasicNameValuePair("hhhh", PhoneNum.toString()));

            UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params, HTTP.UTF_8);
            post.setEntity(ent);

            HttpResponse responsePOST = client.execute(post);
            HttpEntity resEntity = responsePOST.getEntity();
            if (resEntity != null) {
                LoadData = EntityUtils.toString(resEntity, HTTP.UTF_8);

            }
        } catch (IOException e) {
            pDialog.dismiss();
            e.printStackTrace();
        }
        return null;
    }
    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        ViewPager viewPager;
        if(LoadData==null)
        {
            pDialog.dismiss();
            Toast.makeText(GroupChecklist.this, "재접속중..", Toast.LENGTH_SHORT).show();
            LoadMachineSpec a =new LoadMachineSpec();
            a.execute();
        }
        else{
            pDialog.dismiss();
            jsonParse();
            viewPager = (ViewPager) findViewById(R.id.viewpager);
            viewPager.setOffscreenPageLimit(2);
            viewPager.setAdapter(new SampleFragmentPagerAdapter(getSupportFragmentManager(),name_Str,location_Str,state,PhoneNum,viewPager,year,month,breakcount));
            // Give the PagerSlidingTabStrip the ViewPager
            PagerSlidingTabStrip tabsStrip = (PagerSlidingTabStrip) findViewById(R.id.tabs);
            // Attach the view pager to the tab strip
            tabsStrip.setViewPager(viewPager);

        }
    }
}

소스코드 (서버) WAS를 이용하며 doPost로 db연결, 값을 전해주는 역할입니다.

public class DayMachineState extends HttpServlet {
 // 기계이름 , 위치 , 상태 값을 받아와 한번에 보내려함.
 private static final long serialVersionUID = 1L;
 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  request.setCharacterEncoding("UTF-8");
  response.setCharacterEncoding("UTF-8");
  String PhoneNum = request.getParameter("hhhh");
  System.out.println("폰번호 : " + PhoneNum);
  String jsonData;
  JSONObject jObject = new JSONObject();
  JSONArray jArray = new JSONArray();
  DayMachineStateVO vo = new DayMachineStateVO();
  PrintWriter out = response.getWriter();
  getMyName(PhoneNum, vo);
  // 나의 폰번호로 내가 담당하는 기계 이름 서치
  getMyMachine(vo);
  // 등록된 기계 정보를 받아옴
  getMachineRegisted(vo);
  // 기계 현재 상태정보를 받아옴
  getMachineState(vo);
  // 받아온 정보를 대조하여 상태값 추출
   setMachineState(vo);
  // 등록된 기기의 정보를 클라이언트에게 보냄
  sendMachineSpec(vo, jArray);
  jObject.put("day", jArray);
  JSONArray jArrayYear = new JSONArray();
  YearBrokeStateVO VO = new YearBrokeStateVO();
  getYearMahcineBreakCount(VO, jArrayYear);
  getYearWorkingBreakCount(VO, jArrayYear);
  jObject.put("year", jArrayYear);
   jsonData = jObject.toString();
   System.out.println(jsonData);
  out.print(jsonData);

 }
안드로이드하고픈 님이 2017년 1월 4일 질문

2개의 답변

+1 추천
 
채택된 답변
http 통신뿐 아니라 무선 네트워크 특성상 100% 신뢰하기는 힘듭니다. 그렇기에 발생할 수 있는 모든 경우에 예외처리를 하는것이 중요합니다.

코드 확인해보니 커넥트 타임아웃을 2초로 해 놓으셨는데 커넥트 handshake 입장에서 생각하면 2초라는 타임아웃은 너무 짧습니다. 제일 의심되는 부분은 이 부분이므로 타임아웃을 좀 늘려보세요.
Development Guy (70,570 포인트) 님이 2017년 1월 4일 답변
+1 추천
아래 답변하신 분의 답변이 거의 정확합니다.

기본적으로 소켓을 연결하는 시간이 있으니.. 타임아웃 시간을 늘려야 합니다.

그리고, 통신을 하고 결과 처리를 하는 부분은 더 주의해야 합니다.

만약, 서버나 네트웍에 문제가 생긴경우에 무한루프에 빠지는 코드네요..

 

        if(LoadData==null)
        {
            pDialog.dismiss();
            Toast.makeText(GroupChecklist.this, "재접속중..", Toast.LENGTH_SHORT).show();
            LoadMachineSpec a =new LoadMachineSpec();
            a.execute();
        }
mcsong (44,040 포인트) 님이 2017년 1월 4일 답변
네 오류가 발생한다면 데이터를 무조건 로드시켜야하기때문에 올바른 데이터가 로드되기 전까지는 무한반복입니당 답변해주셔서 감사합니다 ^^
보통 에러가 발생하면 계속 에러입니다.. 정말 이 로직이 크리티컬 패스라고 하면.. 2, 3번 이후에는 앱을 종료하는게 좋지 않을까요? 모바일 상황에서 무한루프를 탈 가능성이 꽤 있어 보입니다.
...