일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 안드로이드
- 어플만들기
- 메이플스토리M
- 신혼여행
- 다이소 방울토마토키트
- 쿠폰나눔
- 방울토마토 씨부터 키우기
- 스투키
- 핫엔드
- 괌 신혼여행
- 다크나이트
- 안방농사
- 괌
- 방울토마토키우기
- 에어팟충전기
- 집에서 방울토마토 키우기
- Android
- 집 방울토마토
- 2in1무선충전기
- 겨울나기
- 메이플
- 방토 농사
- 맥세이프충전기
- 괌맛집
- 방울토마토 유기농
- 휴대용무선충전기
- Ender 3 V3 KE
- 메이플스토리
- 다이소 방울토마토
- 보일러절약
Archives
- Today
- Total
괴도군의 블로그
[Android] 채팅서버 / 채팅앱 소스입니다. 본문
반응형
안녕하세요 괴도입니다.
떠돌아다니는 pc버전 자바채팅소스를 앱으로 만들어봤습니다.
소켓통신 그대로 핸드폰에서도 서버를 열고 채팅이 가능합니다
테스트는 공유기환경에서 해주셔야합니다.
ip가져오는부분부터 wifi만 가능하도록 해놨습니다.
하나의폰으로도 채팅테스트가 가능합니다.
( 서버 / 클라이언트 )
AndroidManifest.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.t5online.chat" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
|
cs |
MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
|
package com.t5online.chat;
import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class MainActivity extends Activity implements View.OnClickListener {
private static final int SERVER_TEXT_UPDATE = 100;
private static final int CLIENT_TEXT_UPDATE = 200;
private Button serverCreateButton;//서버열기
private Button serverTransButton;//서버텍스트전송
private Button serverJoinButton;//서버접속
private Button clientTransButton;//클라전송
private TextView serverIpText;//서버아이피확인
private TextView serverText;//서버채팅창
private TextView clientText;//클라채팅창
private EditText joinIpText;//클라접속아이피
private EditText transServerText;
private EditText transClientText;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msgg) {
super.handleMessage(msgg);
switch (msgg.what) {
case SERVER_TEXT_UPDATE: {
serverMsg.append(msg);
serverText.setText(serverMsg.toString());
}
break;
case CLIENT_TEXT_UPDATE: {
clientMsgBuilder.append(clientMsg);
clientText.setText(clientMsgBuilder.toString());
}
break;
}
}
};
//서버세팅
private ServerSocket serverSocket;
private Socket socket;
private String msg;
private StringBuilder serverMsg = new StringBuilder();
private StringBuilder clientMsgBuilder = new StringBuilder();
private Map<String, DataOutputStream> clientsMap = new HashMap<String, DataOutputStream>();
//클라세팅
private Socket clientSocket;
private DataInputStream clientIn;
private DataOutputStream clientOut;
private String clientMsg;
private String nickName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serverCreateButton = (Button) findViewById(R.id.server_create_button);
serverTransButton = (Button) findViewById(R.id.trans_server_button);
serverJoinButton = (Button) findViewById(R.id.server_join_button);
clientTransButton = (Button) findViewById(R.id.trans_client_button);
serverIpText = (TextView) findViewById(R.id.server_ip_text);
serverText = (TextView) findViewById(R.id.server_text);
clientText = (TextView) findViewById(R.id.client_text);
joinIpText = (EditText) findViewById(R.id.join_ip_text);
transServerText = (EditText) findViewById(R.id.trans_server_text);
transClientText = (EditText) findViewById(R.id.trans_client_text);
serverCreateButton.setOnClickListener(this);
serverTransButton.setOnClickListener(this);
serverJoinButton.setOnClickListener(this);
clientTransButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.server_create_button: {
serverIpText.setText(getLocalIpAddress() + ":7777");
serverCreate();
}
break;
case R.id.trans_server_button: {
String msg = "서버 : " + transServerText.getText().toString() + "\n";
serverMsg.append(msg);
serverText.setText(serverMsg.toString());
sendMessage(msg);
transServerText.setText("");
}
break;
case R.id.server_join_button: {
joinServer();
}
break;
case R.id.trans_client_button: {
String msg = nickName + ":" + transClientText.getText() + "\n";
// clientMsgBuilder.append(msg);
// clientText.setText(clientMsgBuilder.toString());
try {
clientOut.writeUTF(msg);
} catch (IOException e) {
e.printStackTrace();
}
transClientText.setText("");
}
break;
}
}
public String getLocalIpAddress() {
WifiManager wifiMgr = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
int ip = wifiInfo.getIpAddress();
String ipAddress = String.format("%d.%d.%d.%d"
, (ip & 0xff)
, (ip >> 8 & 0xff)
, (ip >> 16 & 0xff)
, (ip >> 24 & 0xff));
return ipAddress;
}
public void joinServer() {
if(nickName==null){
nickName="스마트폰";
}
new Thread(new Runnable() {
@Override
public void run() {
try {
clientSocket = new Socket(joinIpText.getText().toString(), 7777);
Log.v("", "클라이언트 : 서버 연결됨.");
clientOut = new DataOutputStream(clientSocket.getOutputStream());
clientIn = new DataInputStream(clientSocket.getInputStream());
//접속하자마자 닉네임 전송하면. 서버가 이걸 닉네임으로 인식을 하고서 맵에 집어넣겠지요?
clientOut.writeUTF(nickName);
Log.v("", "클라이언트 : 메시지 전송완료");
while (clientIn != null) {
try {
clientMsg = clientIn.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(CLIENT_TEXT_UPDATE);
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}).start();
}
public void serverCreate() {
Collections.synchronizedMap(clientsMap);
try {
serverSocket = new ServerSocket(7777);
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
/** XXX 01. 첫번째. 서버가 할일 분담. 계속 접속받는것. */
Log.v("", "서버 대기중...");
try {
socket = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
Log.v("", socket.getInetAddress() + "에서 접속했습니다.");
msg = socket.getInetAddress() + "에서 접속했습니다.\n";
handler.sendEmptyMessage(SERVER_TEXT_UPDATE);
new Thread(new Runnable() {
private DataInputStream in;
private DataOutputStream out;
private String nick;
@Override
public void run() {
try {
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
nick = in.readUTF();
addClient(nick, out);
} catch (IOException e) {
e.printStackTrace();
}
try {// 계속 듣기만!!
while (in != null) {
msg = in.readUTF();
sendMessage(msg);
handler.sendEmptyMessage(SERVER_TEXT_UPDATE);
}
} catch (IOException e) {
// 사용접속종료시 여기서 에러 발생. 그럼나간거에요.. 여기서 리무브 클라이언트 처리 해줍니다.
removeClient(nick);
}
}
}).start();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
public void addClient(String nick, DataOutputStream out) throws IOException {
sendMessage(nick + "님이 접속하셨습니다.");
clientsMap.put(nick, out);
}
public void removeClient(String nick) {
sendMessage(nick + "님이 나가셨습니다.");
clientsMap.remove(nick);
}
// 메시지 내용 전파
public void sendMessage(String msg) {
Iterator<String> it = clientsMap.keySet().iterator();
String key = "";
while (it.hasNext()) {
key = it.next();
try {
clientsMap.get(key).writeUTF(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
clientIn = null;
}
}
|
cs |
activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"
android:focusable="true"
android:focusableInTouchMode="true">
<Button
android:id="@+id/server_create_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="서버열기" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:text="서버아이피" />
<TextView
android:id="@+id/server_ip_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="8"
/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4">
<TextView
android:id="@+id/server_text"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<EditText
android:id="@+id/trans_server_text"
android:layout_width="0dp"
android:layout_weight="8"
android:layout_height="match_parent"
android:hint="서버가 보내는채팅창"/>
<Button
android:id="@+id/trans_server_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:text="전송" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000000" />
<Button
android:id="@+id/server_join_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="서버접속" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:text="접속아이피" />
<EditText
android:id="@+id/join_ip_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="8"
android:hint="아이피 입력"
/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4">
<TextView
android:id="@+id/client_text"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<EditText
android:id="@+id/trans_client_text"
android:layout_width="0dp"
android:layout_weight="8"
android:hint="클라이언트 채팅내용입력"
android:layout_height="match_parent" />
<Button
android:id="@+id/trans_client_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:text="전송" />
</LinearLayout>
</LinearLayout>
|
cs |
테스트 스크린샷
예제 다운로드
github.com/jypDev/android_socket_chat/archive/master.zip
예제 github
반응형
'#프로그래밍 > Android' 카테고리의 다른 글
[PlayStore] 정책위반메일대처 / Android 광고 ID 사용 및 개발자 배포 계약의 4.8 조항을 위반 (0) | 2018.09.27 |
---|---|
[Android] this / MainActivity.this (0) | 2016.12.05 |
[Android] Frame / View 정리 및 커스텀뷰 (0) | 2016.10.20 |
[Android] View Capture / 화면 캡쳐하기 (0) | 2016.10.07 |
[Android]앱에서 APK파일 설치하기 (패키지인스톨러) (0) | 2016.09.08 |
Comments