編輯:關於Android編程
TCP協議:提供IP環境下的數據可靠傳輸,它提供的服務包括數據流傳送、可靠性、有效流控、全雙工操作和多路復用。通過面向連接、端到端和可靠的數據包發送。就如給懸崖上的兩人通信時,他必須先把橋建好,確認橋是沒問題的情況下,才把信件交過去,以後大家每次通信時,都確認下橋沒什麼問題,再通過這座橋來回通信了。
UDP協議:不為IP提供可靠性、流控或差錯恢復功能,在正式通信前不必與對方先建立連接,不管對方狀態就直接發送。這個就是飛鴿傳書了~
雖然UDP可靠性不如TCP協議,但是通信效率高於TCP。在網速極差的情況下優先考慮UDP協議,網速好的話TCP還是很方便使用的。
在Java中使用TCP可以通過java.net.Socket;這個類
建立連接
//實例化一個Socket對象 socket = new Socket(); //與對應的ip、端口進行連接,先要把橋建好 socket.connect(new InetSocketAddress(ip, port), 3000);
發送信息
InputStream ois = socket.getInputStream(); DataInputStream dis = new DataInputStream(new BufferedInputStream(ois)); //讀取服務器發過來的信息,如果沒信息將會阻塞線程 msg = dis.readUTF();
發送信息
//獲得輸出流 DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); //發送數據 dos.writeUTF(msg);
接下來上源碼,為三個Thread的子類,分別對應上面三個
public class SocketThread extends Thread{
private Socket socket;
private Client client;
private String ip;
private int port;
private boolean isStart=false;
private MessageListener mMessageListener;
/**
*
* 使用TCP協議,連接訪問
* @param ip 目標機器的IP
* @param port 端口
* @param mMessageListener 收到服務器端數據時將回調該接口內的
* public void Message(String msg)方法
*/
public SocketThread(String ip, int port,
MessageListener mMessageListener) {
this.ip = ip;
this.port = port;
this.mMessageListener = mMessageListener;
}
public void run() {
try {
//實例化一個Socket對象
socket = new Socket();
//與對應的ip、端口進行連接,先要把橋建好
socket.connect(new InetSocketAddress(ip, port), 3000);
if (socket.isConnected()) {
System.out.println("Connected..");
client = new Client(socket,mMessageListener);
//打開對應的輸入/輸出流監聽
client.start();
isStart=true;
}
} catch (IOException e) {
e.printStackTrace();
isStart=false;
}
}
// 直接通過client得到讀線程
public ClientInputThread getClientInputThread() {
return client.getIn();
}
// 直接通過client得到寫線程
public ClientOutputThread getClientOutputThread() {
return client.getOut();
}
//返回Socket狀態
public boolean isStart(){
return isStart;
}
// 直接通過client停止讀寫消息
public void setIsStart(boolean isStart) {
this.isStart = isStart;
client.getIn().setStart(isStart);
client.getOut().setStart(isStart);
}
//發送消息
public void sendMsg(String msg){
client.getOut().sendMsg(msg);
}
public class Client {
private ClientInputThread in;
private ClientOutputThread out;
public Client(Socket socket,MessageListener mMessageListener) {
//用這個監聽輸入流線程來接收信息
in = new ClientInputThread(socket);
in.setMessageListener(mMessageListener);
//以後就用這個監聽輸出流的線程來發送信息了
out = new ClientOutputThread(socket);
}
public void start() {
in.setStart(true);
out.setStart(true);
in.start();
out.start();
}
// 得到讀消息線程
public ClientInputThread getIn() {
return in;
}
// 得到寫消息線程
public ClientOutputThread getOut() {
return out;
}
}
}public class ClientInputThread extends Thread {
private Socket socket;
private String msg;
private boolean isStart = true;
private InputStream ois;
private DataInputStream dis;
private MessageListener messageListener;// 消息監聽接口對象
public ClientInputThread(Socket socket) {
this.socket = socket;
try {
ois = socket.getInputStream();
dis = new DataInputStream(new BufferedInputStream(ois));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 提供給外部的消息監聽方法
*
* @param messageListener
* 消息監聽接口對象
*/
public void setMessageListener(MessageListener messageListener) {
this.messageListener = messageListener;
}
public void setStart(boolean isStart) {
this.isStart = isStart;
}
@Override
public void run() {
try {
while (isStart) {
//讀取信息,如果沒信息將會阻塞線程
msg = dis.readUTF();
// 每收到一條消息,就調用接口的方法Message(String msg)
Log.v("收到消息", msg);
messageListener.Message(msg);
}
ois.close();
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
BufferedReader reader=null;
public String getInputStreamString() {
/*
* To convert the InputStream to String we use the
* BufferedReader.readLine() method. We iterate until the BufferedReader
* return null which means there's no more data to read. Each line will
* appended to a StringBuilder and returned as String.
*/
if (ois != null) {
reader = new BufferedReader(new InputStreamReader(ois));
}
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}public class ClientOutputThread extends Thread {
private Socket socket;
private DataOutputStream dos;
private boolean isStart = true;
private String msg;
public ClientOutputThread(Socket socket) {
this.socket = socket;
try {
dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void setStart(boolean isStart) {
this.isStart = isStart;
}
// 這裡處理跟服務器是一樣的
public void sendMsg(String msg) {
this.msg = msg;
synchronized (this) {
notifyAll();
}
}
@Override
public void run() {
try {
while (isStart) {
if (msg != null) {
dos.writeUTF(msg);
dos.flush();
msg=null;
synchronized (this) {
wait();// 發送完消息後,線程進入等待狀態
}
}
}
dos.close();// 循環結束後,關閉輸出流和socket
if (socket != null)
socket.close();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}//定義接收到消息時的,處理消息的接口
public interface MessageListener {
public void Message(String msg);
}
主界面,感覺很丑,將就吧
"
public class MainActivity extends Activity {
EditText etMessage;
TextView tvSend, tvMessage;
SocketThread client;
MyHandler myHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setup();
}
public void setup() {
etMessage = (EditText) findViewById(R.id.etMessage);
tvSend = (TextView) findViewById(R.id.tvSend);
tvMessage = (TextView) findViewById(R.id.tvMessage);
tvSend.setOnClickListener(onClick);
myHandler = new MyHandler();
//初始化
client = new SocketThread("10.21.56.226", 8888,new MessageListener() {
//收到消息後調用此方法
@Override
public void Message(String msg) {
// TODO Auto-generated method stub
// tvMessage.append(msg);
Bundle bundle = new Bundle();
bundle.putString("input", msg);
Message isMessage = new Message();
isMessage.setData(bundle);
//使用handler轉發
myHandler.sendMessage(isMessage);
}
});
//正式啟動線程
client.start();
}
OnClickListener onClick = new OnClickListener() {
public void onClick(android.view.View v) {
String message = etMessage.getText().toString();
Log.v("發送消息", message);
if (client.isStart()) {
client.sendMsg(message);
}
};
};
private class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.v("處理收到的消息", " ");
tvMessage.append(msg.getData().getString("input"));
}
}
}public class ChatServer {
boolean started = false;
ServerSocket ss = null;
List clients = new ArrayList();
public static void main(String[] args) {
new ChatServer().start();
}
public void start() {
try {
//ServerSocket監聽8888端口
ss = new ServerSocket(8888);
started = true;
} catch (BindException e) {
System.out.println("start....");
System.out.println("有問題");
e.printStackTrace();
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
try {
while (started) {
Socket s = ss.accept();
Client c = new Client(s);
System.out.println("a client connected!");
new Thread(c).start();
clients.add(c);
// dis.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Client implements Runnable {
private Socket s;
private DataInputStream dis = null;
private DataOutputStream dos = null;
private boolean bConnected = false;
public Client(Socket s) {
this.s = s;
try {
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
bConnected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String str) {
try {
dos.writeUTF(str);
} catch (IOException e) {
clients.remove(this);
System.out.println("關閉一個連接");
// e.printStackTrace();
}
}
public void run() {
try {
while (bConnected) {
String str = dis.readUTF();
System.out.println(str);
for (int i = 0; i < clients.size(); i++) {
Client c = clients.get(i);
c.send(str);
// System.out.println(" a string send !");
}
/*
* for(Iterator it = clients.iterator();
* it.hasNext(); ) { Client c = it.next(); c.send(str); }
*/
/*
* Iterator it = clients.iterator();
* while(it.hasNext()) { Client c = it.next(); c.send(str);
* }
*/
}
} catch (EOFException e) {
System.out.println("Client closed!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
System.out.println("close All !");
if (dis != null)
dis.close();
if (dos != null)
dos.close();
if (s != null) {
s.close();
// s = null;
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
} 接下來先運行服務器代碼,再運行手機端就可以了,多台手機可以互相發送信息了。
Android百日程序:高效載入大圖片
問題:如果圖片很大,全部載入內存,而顯示屏又不大,那麼再大的圖片也不會提高視覺效果的,而且會消耗無謂的內存。 解決辦法就是根據實際需要多大的圖片,然後動態計算應該載入多大
Android_Sqlbrite入門使用
除非迫不得已,要不然不要在你的APP裡面使用數據庫,記不得是哪個書的話了!現在Android平台下的ORM框架very多,比如GreenDao,曾經寫過一篇關於Green
Android安卓安全審計mobiseclab
關於安卓上的app分析,有很多的本地化軟件可以勝任, 不過,今天給大家介紹一款在線的安全審計,惡意軟件(android app)檢測和分析工具,mobiseclab,
Android UI控件ExpandableListView基本用法詳解
ExpandableListView介紹 ExpandableListView的引入 ExpandableListView可以顯示一個視圖垂直滾動顯示
Error running app: Instant Run requires 'Tools | Android | Enable ADB integration' to be enabled.
今早起來運行程序 一直報這個錯Error running app: In