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

소켓 통신시 첫 단어가 꾸준하게 잘립니다.

0 추천
계속 하고 있는데 이상하게 계속해서 잘립니다.

처음에 할 땐 잘 되었던 것 같은데, 다시 확인하니 잘 안되니 답답하네요.

 

와이파이로 PC와 접속해서 123을 보내면 123을 보내면 456을 반환하도록 한 PC에서 통신을 보내면 56만 출력이 됩니다.

(물론 따로 보내도 56만 나옵니다. abc를 보내면 bc만 나오더라고요.)

 

byte 어레이를 read 한 부분을 확인하면 이미 첫글자가 날라간 상태라...

inputstream에서 확인을 하고 싶은데 어떻게 확인해야 하는지를 모르겠습니다.

확인하는 방법이 있나요?

 

아니면 제 코드가 잘못 된 것인지 확인 부탁 드려도 될지요.
미친공대생 (270 포인트) 님이 2015년 8월 24일 질문
public class InternetActivity extends Activity {
    private Context context;
    
    private EditText edittextIPnPort;
    private Button   buttonConnect;
    private Button   buttonDisconnect;
    
    private EditText editviewView;
    private EditText editviewMessage;
    private Button   buttonSend;   
  
    /// @brief   socket이 사전에 정의된 client를 가져온다.
    private SocketClient client;
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        StrictMode.enableDefaults();  
        setContentView(R.layout.activity_internet);   
        context = this;
       
        // socket 설정 :
        client = SocketClient.getInstance();       
       
        // connect
        edittextIPnPort  = (EditText)findViewById(R.id.activity_internet_edittext_connect_ipport);       
        buttonConnect    = (Button)findViewById(R.id.activity_internet_button_connect_connect);
        buttonDisconnect = (Button)findViewById(R.id.activity_internet_button_connect_disconnect);
        // view
        editviewView     = (EditText)findViewById(R.id.activity_internet_edittext_communication_view);
        editviewMessage  = (EditText)findViewById(R.id.activity_internet_edittext_communication_message);
        buttonSend       = (Button)findViewById(R.id.activity_internet_button_communication_send);
       
       
        // Connect Button Click
        buttonConnect.setOnClickListener( new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // socket 연결
                if( client.connect( edittextIPnPort.getText().toString() ) ){// ui 제어
                    client.start();
                    client.setReadHandler( new Handler(){
                        @Override
                        public void handleMessage(Message msg){                           
                            String in = new String( msg.getData().getString("read") );
                            addLineView(in, true);
                        }
                    });
//                    client.setOnReadListener( new SocketClient.OnReadListener(){
//                            public void onListener(byte[] buf, int size){
//                                String in = new String( client.read() );
//                                addLineView(in, true);
//                            }
//                        });
                   
                   
                    buttonConnect.setEnabled(false);  // 버튼 비활성화
                    buttonDisconnect.setEnabled(true);  // 버튼 활성화
                    JHsViewAndroid.okAlertDialog(context, "연결에 성공하였습니다.");
                }else{
                    client.stop();
                    JHsViewAndroid.okAlertDialog(context, "연결에 실패하였습니다.");
                    buttonConnect.setEnabled(true);  // 버튼 활성화
                    buttonDisconnect.setEnabled(false);  // 버튼 비활성화
                }
            }
        });
       
       
        //Disconnect Button Click
        buttonDisconnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                if( client.disconnect() ){
                    client.stop();
                    buttonConnect.setEnabled(true);  // 버튼 활성화
                    buttonDisconnect.setEnabled(false);  // 버튼 비활성화
                }else{
                    buttonConnect.setEnabled(false);    //Connect 버튼 비활성화
                    buttonConnect.setEnabled(false);  // 버튼 비활성화
                    buttonDisconnect.setEnabled(true);  // 버튼 활성화
                }
            }
        });
       
       
        //Send Button Click
        buttonSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {      
                String out = editviewMessage.getText().toString();
                addLineView(out, false);
                client.write(out.getBytes());
                editviewMessage.setText(""); // 전송후 내용 삭제
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        return super.onOptionsItemSelected(item);
    }
   
   
    /////////////////////////////////////////////////////////////////////////////

    /// @param   string, editview에 추가할 글
    /// @param   mode, true : read \n
    ///                false : write
    private void addLineView(String string, boolean mode){
        if( mode ) editviewView.setText( editviewView.getText().toString() + "[in] " + string + "\n");
        else       editviewView.setText( editviewView.getText().toString() + "[out] " + string + "\n");
    }

}
public class SocketClient {
    private final boolean debug_status = true;
    private final String  debug_name   = "ServiceInternet";
   
       
    /////////////////////////////////////////////////////////////
   
    // singleton 구현됨
    private static SocketClient instance = new SocketClient();
   
    /// @brief   socket clinet 정의 하였함
    private Socket       socket;
    /// @brief   수신한  socket data
    private InputStream  socket_in;
    /// @brief   전솔할  socket data
    private OutputStream socket_out;
    
    /// @brief   socket에서 사용할 thread
    private Thread       socketThread;
    private boolean      socketFlag;
    
    // singleton 구현됨
    private SocketClient(){
        // socket통신은 ui에 영향을 주므로 즉각 반응 모드 활성화 필요.
        StrictMode.enableDefaults();  
    }
    
    public static SocketClient getInstance(){
        if(instance == null) instance = new SocketClient();
        return instance;
    }
    
    
    ////////////////////////////////////////////////////////////////////////
    
    public boolean connect(String address){
        String  ip   = address.split(":")[0];
        Integer port = Integer.valueOf( address.split(":")[1] );
       
        try{
            // socket 연결
            socket = new Socket(ip, port);
           
            // in/out stream 연결
            socket_in  = socket.getInputStream();
            socket_out = socket.getOutputStream();
           
            // socket 구성 성공후 thread 생성
            socketThread = new Thread(new Runnable(){
                public void run(){
                    try {
                        int size = 0;
                        while(socketFlag){
                            socket_in  = socket.getInputStream();
                            size = socket_in.read();  // 데이터의 길이 얻기
                            if(size > 0){
                                byte[] read = new byte[size];  // 들어온 길이 만큼  byte 생성
                                socket_in.read(read); // 데이터를 읽는다.
                                sendHandlerMessage(handler.obtainMessage() , read);
                                if( debug_status ) Log.i(debug_name, "read{" + size + "):"+ new String(byteRead)  );
                            }
                        }
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            });

            socketFlag = false;
            if( debug_status ) Log.i(debug_name, "connecting success");
            return true;
        }catch(Exception e){
            socketFlag = false;
            if( debug_status ) Log.e(debug_name, "connecting error : " + e.toString());
            return false;
        }
    }
    
    public boolean disconnect(){
        try{
            // socket 종료
            socket.close();
            socketFlag = false;
            if( debug_status ) Log.i(debug_name, "connecting exit");
            return true;
        }
        catch(Exception e)
        {
            if( debug_status ) Log.e(debug_name, "connecting  exit error : " + e.toString() );
            return false;
        }
    }
   
    public boolean start(){
        socketFlag = true;
        socketThread.start();  
        if( debug_status ) Log.i(debug_name, "thread start!!!");     
        return true;
    }
    
    public boolean stop(){
        socketFlag = false;       
        if( debug_status ) Log.i(debug_name, "thread stop!!!");
        return true;
    }
    
    
    ////////////////////////////////////////////////////////////////////////     
    
    public boolean write(OutputStream out){
        try {
//            socket_out = out;
            if( debug_status ) Log.i(debug_name, "write : " + out.toString());
            return true;
        } catch (Exception e) {
            if( debug_status ) Log.e(debug_name, "write error : " + e.toString());
            return true;
        }
    }    
    /// @note   write 를 byte[]으로 할수 있도록 overload 함.
    public boolean write(byte[] out){
        try {
            socket_out = socket.getOutputStream();
            socket_out.write( out );
            if( debug_status ) Log.i(debug_name, "write : " + new String(out) );
            return true;
        } catch (Exception e) {
            if( debug_status ) Log.e(debug_name, "write error : " + e.toString());
            return false;
        }
    }
    
    
  
    private OnReadListener listenerRead = null;
    private Handler        handler  = null;
    private byte[]         byteRead     = null;
  
    /// @brief   외부에서 read한 data를 받기 위한 listener 받기  
    public interface OnReadListener{
        public abstract void onListener(byte[] buf, int size);
    }
    public void setOnReadListener(OnReadListener listener ){
        listenerRead = listener;
    }
   
   
    public void setReadHandler(Handler handler ){
        this.handler = handler;
    }
    private synchronized void sendHandlerMessage(Message message, byte[] read) {
        // TODO Auto-generated method stub
        Bundle bundle = new Bundle();
        bundle.putString("read", new String(read) );
        message.setData(bundle);   
        handler.sendMessage(message);
    }
    
    ////////////////////////////////////////////////////////////////////////     
    
}
길어서 못들어가 덧글로 남깁니다.

1개의 답변

0 추천
 
채택된 답변

사이즈를 구한  size = socket_in.read();  가 이상한데요.

write할 때 사이즈를 보냈으면, 이상없는 코드이지만.

 

write 할 땐 사이즈를 보내지 않고 socket_out.write( out ); 만  하신 듯 한데요...

 

 socket_out.write( out ); 이전에 사이즈도 보내시던지. 

읽는 곳에서  사이즈 만큼 byte array를 구하는 것 대신  무조건 읽어 Stringbuffer append 등으로 합쳐 사용하셔야 할 듯 합니다.

사악미소 (65,330 포인트) 님이 2015년 8월 24일 답변
미친공대생님이 2015년 8월 24일 채택됨
감사합니다. ㅠㅠ 겨우 해결 된 듯 합니다. buffered를 이용해서 하니 바로 되네요. 답변 주셔서 감사 드립니다.
...