Android學習筆記三十六:android之socket程式設計例項
阿新 • • 發佈:2019-01-01
注意點:註冊訪問的網路許可權;android中UI執行緒不能有訪問網路的操作,否則會報android.os.NetworkOnMainThreadException的異常
<uses-permission
android:name="android.permission.INTERNET"/>
Android開發聯盟③ 433233634例項一
客戶端
package com.android.xiong.simplesocket; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity { Socket socket = null; String buffer = ""; TextView txt1; Button send; EditText ed1; String geted1; public Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0x11) { Bundle bundle = msg.getData(); txt1.append("server:"+bundle.getString("msg")+"\n"); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txt1 = (TextView) findViewById(R.id.txt1); send = (Button) findViewById(R.id.send); ed1 = (EditText) findViewById(R.id.ed1); send.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { geted1 = ed1.getText().toString(); txt1.append("client:"+geted1+"\n"); //啟動執行緒 向伺服器傳送和接收資訊 new MyThread(geted1).start(); } }); } class MyThread extends Thread { public String txt1; public MyThread(String str) { txt1 = str; } @Override public void run() { //定義訊息 Message msg = new Message(); msg.what = 0x11; Bundle bundle = new Bundle(); bundle.clear(); try { //連線伺服器 並設定連線超時為5秒 socket = new Socket(); socket.connect(new InetSocketAddress("1.1.9.30", 30000), 5000); //獲取輸入輸出流 OutputStream ou = socket.getOutputStream(); BufferedReader bff = new BufferedReader(new InputStreamReader( socket.getInputStream())); //讀取發來伺服器資訊 String line = null; buffer=""; while ((line = bff.readLine()) != null) { buffer = line + buffer; } //向伺服器傳送資訊 ou.write("android 客戶端".getBytes("gbk")); ou.flush(); bundle.putString("msg", buffer.toString()); msg.setData(bundle); //傳送訊息 修改UI執行緒中的元件 myHandler.sendMessage(msg); //關閉各種輸入輸出流 bff.close(); ou.close(); socket.close(); } catch (SocketTimeoutException aa) { //連線超時 在UI介面顯示訊息 bundle.putString("msg", "伺服器連線失敗!請檢查網路是否開啟"); msg.setData(bundle); //傳送訊息 修改UI執行緒中的元件 myHandler.sendMessage(msg); } catch (IOException e) { e.printStackTrace(); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <EditText android:id="@+id/ed1" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="給伺服器傳送資訊"/> <Button android:id="@+id/send" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/ed1" android:text="傳送"/> <TextView android:id="@+id/txt1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/send"/> </RelativeLayout>
服務端
package com.android.net; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; public class AndroidService { public static void main(String[] args) throws IOException { ServerSocket serivce = new ServerSocket(30000); while (true) { //等待客戶端連線 Socket socket = serivce.accept(); new Thread(new AndroidRunable(socket)).start(); } } }
package com.android.net;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class AndroidRunable implements Runnable {
Socket socket = null;
public AndroidRunable(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// 向android客戶端輸出hello worild
String line = null;
InputStream input;
OutputStream output;
String str = "hello world!";
try {
//向客戶端傳送資訊
output = socket.getOutputStream();
input = socket.getInputStream();
BufferedReader bff = new BufferedReader(
new InputStreamReader(input));
output.write(str.getBytes("gbk"));
output.flush();
//半關閉socket
socket.shutdownOutput();
//獲取客戶端的資訊
while ((line = bff.readLine()) != null) {
System.out.print(line);
}
//關閉輸入輸出流
output.close();
bff.close();
input.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
例項二
客戶端
package com.android.xiong.sockettwotest;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
// 定義介面上的兩個文字框
EditText input;
TextView show;
// 定義介面上的一個按鈕
Button send;
Handler handler;
// 定義與伺服器通訊的子執行緒
ClientThread clientThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
input = (EditText) findViewById(R.id.input);
show = (TextView) findViewById(R.id.show);
send = (Button) findViewById(R.id.send);
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// 如果訊息來自子執行緒
if (msg.what == 0x123) {
// 將讀取的內容追加顯示在文字框中
show.append("\n" + msg.obj.toString());
}
}
};
clientThread = new ClientThread(handler);
// 客戶端啟動ClientThread執行緒建立網路連線、讀取來自伺服器的資料
new Thread(clientThread).start();
send.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
// 當用戶按下按鈕之後,將使用者輸入的資料封裝成Message
// 然後傳送給子執行緒Handler
Message msg = new Message();
msg.what = 0x345;
msg.obj = input.getText().toString();
clientThread.revHandler.sendMessage(msg);
input.setText("");
} catch (Exception e) {
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
package com.android.xiong.sockettwotest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
public class ClientThread implements Runnable {
private Socket s;
// 定義向UI執行緒傳送訊息的Handler物件
Handler handler;
// 定義接收UI執行緒的Handler物件
Handler revHandler;
// 該執行緒處理Socket所對用的輸入輸出流
BufferedReader br = null;
OutputStream os = null;
public ClientThread(Handler handler) {
this.handler = handler;
}
@Override
public void run() {
s = new Socket();
try {
s.connect(new InetSocketAddress("1.1.9.30", 3000), 5000);
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
os = s.getOutputStream();
// 啟動一條子執行緒來讀取伺服器相應的資料
new Thread() {
@Override
public void run() {
String content = null;
// 不斷的讀取Socket輸入流的內容
try {
while ((content = br.readLine()) != null) {
// 每當讀取到來自伺服器的資料之後,傳送的訊息通知程式
// 介面顯示該資料
Message msg = new Message();
msg.what = 0x123;
msg.obj = content;
handler.sendMessage(msg);
}
} catch (IOException io) {
io.printStackTrace();
}
}
}.start();
// 為當前執行緒初始化Looper
Looper.prepare();
// 建立revHandler物件
revHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// 接收到UI執行緒的中使用者輸入的資料
if (msg.what == 0x345) {
// 將使用者在文字框輸入的內容寫入網路
try {
os.write((msg.obj.toString() + "\r\n")
.getBytes("gbk"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
// 啟動Looper
Looper.loop();
} catch (SocketTimeoutException e) {
Message msg = new Message();
msg.what = 0x123;
msg.obj = "網路連線超時!";
handler.sendMessage(msg);
} catch (IOException io) {
io.printStackTrace();
}
}
}
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<EditText
android:id="@+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/input" />
<Button
android:id="@+id/send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/send"
android:layout_below="@id/input"/>
<TextView
android:id="@+id/show"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/send"/>
</RelativeLayout>
服務端
package com.android.net;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class MyService {
// 定義儲存所有的Socket
public static List<Socket> socketList = new ArrayList<Socket>();
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(3000);
while(true){
Socket s=server.accept();
socketList.add(s);
//每當客戶端連線之後啟動一條ServerThread執行緒為該客戶端服務
new Thread(new ServiceThreada(s)).start();
}
}
}
package com.android.net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class ServiceThreada implements Runnable {
// 定義當前執行緒處理的Socket
Socket s = null;
// 該執行緒所處理的Socket所對應的輸入流
BufferedReader br = null;
public ServiceThreada(Socket s) {
this.s = s;
try {
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String content = null;
//採用迴圈不斷的從Socket中讀取客戶端傳送過來的資料
while((content=readFromClient())!=null){
//遍歷socketList中的每個Socket
//將讀取到的內容每個向Socket傳送一次
for(Socket s:MyService.socketList){
OutputStream os;
try {
os = s.getOutputStream();
os.write((content+"\n").getBytes("gbk"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
// 定義讀取客戶端的資訊
public String readFromClient() {
try {
return br.readLine();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}