IPC 机制---使用Socket
Socket 也称套接字 ,是网络通信中的概念,它分为流式套接字 和用户数据报套接字 两种
Socket 也称套接字 ,是网络通信中的概念,它分为流式套接字 和用户数据报套接字 两种
流式套接字 :对应于传输控制层的TCP协议 TCP协议 是面向连接的协议,提供稳定的双向通信功能,TCP的连接需要经过三次握手才能完成,为了提供稳定的数据传输功能,其本身提供了超时重传机制,因此具有很高的稳定性。
用户数据报套接字:对应于传输控制层的UDP协议,UDP是无连接的,提供不稳定的单向通信功能,当然UDP也可以实现双向通信功能。在性能上UDP具有更好的效率,其缺点是不能保证数据一定能够正确传输,尤其是在网络拥塞的情况下。
使用 Socket 来进行通信首先需要声明权限
<uses-permission android:name= "android.permission.INTERNET" />
<
uses-permission
android:name
=
"android.permission.ACCESS_NETWORK_STATE"
/>
其次不能够在主线程中访问网络,因为这会导致我们的程序无法在Android4.0 以上的设备运行。而且进行网络操作很可能是耗时的,如果放在主线程的中,会影响程序的响应效率。
服务端代码:
public
class
TCPServerService
extends
Service {
private
boolean
mIsServiceDestoryed
=
false
;
private
String[]
mDefinedMessages
=
new
String[] {
"浣犲ソ鍟婏紝鍝堝搱"
,
"璇烽棶浣犲彨浠�涔堝悕瀛楀憖锛�"
,
"浠婂ぉ鍖椾含澶╂皵涓嶉敊鍟婏紝shy"
,
"浣犵煡閬撳悧锛熸垜鍙槸鍙互鍜屽涓汉鍚屾椂鑱婂ぉ鐨勫摝"
,
"缁欎綘璁蹭釜绗戣瘽鍚э細鎹鐖辩瑧鐨勪汉杩愭皵涓嶄細澶樊锛屼笉鐭ラ亾鐪熷亣銆�"
};
@Override
public
void
onCreate() {
new
Thread(
new
TcpServer()).start();
super
.onCreate();
}
@Override
public
IBinder onBind(Intent intent) {
return
null
;
}
@Override
public
void
onDestroy() {
mIsServiceDestoryed
=
true
;
super
.onDestroy();
}
private
class
TcpServer
implements
Runnable {
@SuppressWarnings
(
"resource"
)
@Override
public
void
run() {
ServerSocket serverSocket =
null
;
try
{
serverSocket =
new
ServerSocket(8688);
}
catch
(IOException e) {
System.
err
.println(
"establish tcp server failed, port:8688"
);
e.printStackTrace();
return
;
}
while
(!
mIsServiceDestoryed
) {
try
{
// 鎺ュ彈瀹㈡埛绔姹�
final
Socket client = serverSocket.accept();
System.
out
.println(
"accept"
);
new
Thread() {
@Override
public
void
run() {
try
{
responseClient(client);
}
catch
(IOException e) {
e.printStackTrace();
}
};
}.start();
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
}
private
void
responseClient(Socket client)
throws
IOException {
// 用于接收客户端消息
BufferedReader in =
new
BufferedReader(
new
InputStreamReader(
client.getInputStream()));
// 用于向客户端发送消息
PrintWriter out =
new
PrintWriter(
new
BufferedWriter(
new
OutputStreamWriter(client.getOutputStream())),
true
);
out.println(
"娆㈣繋鏉ュ埌鑱婂ぉ瀹わ紒"
);
while
(!
mIsServiceDestoryed
) {
String str = in.readLine();
System.
out
.println(
"msg from client:"
+ str);
if
(str ==
null
) {
//客户端断开连接
break
;
}
int
i =
new
Random().nextInt(
mDefinedMessages
.
length
);
String msg =
mDefinedMessages
[i];
out.println(msg);
System.
out
.println(
"send :"
+ msg);
}
System.
out
.println(
"client quit."
);
// 鍏抽棴娴�
MyUtils. close(out);
MyUtils. close(in);
client.close();
}
}
客户端代码:
public
class
TCPClientActivity
extends
Activity
implements
OnClickListener {
private
static
final
int
MESSAGE_RECEIVE_NEW_MSG
= 1;
private
static
final
int
MESSAGE_SOCKET_CONNECTED
= 2;
private
Button
mSendButton
;
private
TextView
mMessageTextView
;
private
EditText
mMessageEditText
;
private
PrintWriter
mPrintWriter
;
private
Socket
mClientSocket
;
@SuppressLint
(
"HandlerLeak"
)
private
Handler
mHandler
=
new
Handler() {
@Override
public
void
handleMessage(Message msg) {
switch
(msg.
what
) {
case
MESSAGE_RECEIVE_NEW_MSG
: {
mMessageTextView
.setText(
mMessageTextView
.getText()
+ (String) msg.
obj
);
break
;
}
case
MESSAGE_SOCKET_CONNECTED
: {
mSendButton
.setEnabled(
true
);
break
;
}
default
:
break
;
}
}
};
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.
activity_tcpclient
);
mMessageTextView
= (TextView) findViewById(R.id.
msg_container
);
mSendButton
= (Button) findViewById(R.id.
send
);
mSendButton
.setOnClickListener(
this
);
mMessageEditText
= (EditText) findViewById(R.id.
msg
);
Intent service =
new
Intent(
this
, TCPServerService.
class
);
startService(service);
new
Thread() {
@Override
public
void
run() {
connectTCPServer();
}
}.start();
}
@Override
protected
void
onDestroy() {
if
(
mClientSocket
!=
null
) {
try
{
mClientSocket
.shutdownInput();
mClientSocket
.close();
}
catch
(IOException e) {
e.printStackTrace();
}
}
super
.onDestroy();
}
@Override
public
void
onClick(View v) {
if
(v ==
mSendButton
) {
final
String msg =
mMessageEditText
.getText().toString();
if
(!TextUtils.isEmpty(msg) &&
mPrintWriter
!=
null
) {
mPrintWriter
.println(msg);
mMessageEditText
.setText(
""
);
String time = formatDateTime(System. currentTimeMillis());
final
String showedMsg =
"self "
+ time +
":"
+ msg +
"\n"
;
mMessageTextView
.setText(
mMessageTextView
.getText() + showedMsg);
}
}
}
@SuppressLint
(
"SimpleDateFormat"
)
private
String formatDateTime(
long
time) {
return
new
SimpleDateFormat(
"(HH:mm:ss)"
).format(
new
Date(time));
}
private
void
connectTCPServer() {
Socket socket =
null
;
while
(socket ==
null
) {
try
{
socket =
new
Socket(
"localhost"
, 8688);
mClientSocket
= socket;
mPrintWriter
=
new
PrintWriter(
new
BufferedWriter(
new
OutputStreamWriter(socket.getOutputStream())),
true
);
mHandler
.sendEmptyMessage(
MESSAGE_SOCKET_CONNECTED
);
System.
out
.println(
"connect server success"
);
}
catch
(IOException e) {
SystemClock. sleep(1000);
System.
out
.println(
"connect tcp server failed, retry..."
);
}
}
try
{
// 鎺ユ敹鏈嶅姟鍣ㄧ鐨勬秷鎭�
BufferedReader br =
new
BufferedReader(
new
InputStreamReader(
socket.getInputStream()));
while
(!TCPClientActivity.
this
.isFinishing()) {
String msg = br.readLine();
System.
out
.println(
"receive :"
+ msg);
if
(msg !=
null
) {
String time = formatDateTime(System. currentTimeMillis());
final
String showedMsg =
"server "
+ time +
":"
+ msg
+
"\n"
;
mHandler
.obtainMessage(
MESSAGE_RECEIVE_NEW_MSG
, showedMsg)
.sendToTarget();
}
}
System.
out
.println(
"quit..."
);
MyUtils. close(
mPrintWriter
);
MyUtils. close(br);
socket.close();
}
catch
(IOException e) {
e.printStackTrace();
}
}
}