본문 바로가기

Android/Basic

[Android] Socket 통신 예제

최신 글(kotlin) 보러가기 - 20.09.28 업데이트


- 2-tier C/S 모델 : 서버와 클라이언트가 1대1로 연결되어, 요청 응답 주고받음

- 3-tier 모델

- 서버를 좀 더 유연하게 구성

- 응용서버와 데이터서버로 구성하는 경우로, 데이터베이스를 분리시킴.

- 중간에 있는 서버를 애플리케이션 서버 또는 미드웨어라고 함


1. 소켓 연결을 위한 socket 객체 생성

2. 데이터를 쓰기 위한 스트림 객체를 만들고 데이터 쓰기

3. 데이터를 읽기 위한 스트림 객체를 만들고 데이터 읽기


환경은 동일 단말


0. 서버, 클라이언트 매니페스트에 인터넷 권한 추가

<uses-permission android:name="android.permission.INTERNET"/>


1. 서버 애플리케이션(서비스)

void onCreate() {
// 초기화 되는 시점. 스레드 실행
super.onCreate();
ServerThread thread = new ServerThread();
thread.start();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
super.onDestroy();
}

@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}

class ServerThread extends Thread {
@Override
public void run() {
int port = 5001;
try {
ServerSocket server = new ServerSocket(port);
Log.d("ServerThread", "서버가 실행됨.");

while(true){
Socket socket = server.accept(); // server 대기상태. 클라이언트 접속 시 소켓 객체 리턴

ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream()); // 들어오는 데이터 처리
Object input = inputStream.readObject();
Log.d("ServerThread","input : "+input);

ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeObject(input + "from server"); // 서버에서 보낸 데이터
outputStream.flush();
Log.d("ServerThread","output 보냄");

socket.close(); // 연결을 유지할 필요 없으면 끊어줌.
}
} catch (Exception e){
e.printStackTrace();
}
}
}
}

startServer(intent)로 서비스 시작


2. 클라이언트 애플리케이션

class ClientThread extends Thread {
public void run() {
String host = "localhost";
int port = 5001;

try {
Socket socket = new Socket(host, port);

ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeObject("안녕!");
outputStream.flush();
Log.d("ClientThread", "서버로 보냄.");
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
final String input = (String) inputStream.readObject(); // Object로 받아도 무방
Log.d("ClientThread","받은 데이터 : "+input);

handler.post(new Runnable() {
@Override
public void run() {
textView.setText("받은 데이터 : "+input);
}
});

} catch (Exception e) {
e.printStackTrace();
}
}
}

핸들러를 통해 UI 접근

findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ClientThread thread = new ClientThread();
thread.start();
}
});

클릭시 클라이언트 스레드를 생성하여 서버로 요청.