日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

即时通讯基础

發(fā)布時(shí)間:2025/4/16 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 即时通讯基础 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

即時(shí)通訊系列閱讀

  • 即時(shí)通訊基礎(chǔ)
  • 即時(shí)通訊:XMPP基礎(chǔ)
  • 即時(shí)通訊:XMPP項(xiàng)目實(shí)踐-微聊
  • Smack類庫最好的學(xué)習(xí)資料
  • 1. 即時(shí)通訊簡介

    即時(shí)通訊(Instant Messaging)是目前Internet 上最為流行的通訊方式,各種各樣的即時(shí)通訊軟件也層出不窮;服務(wù)提供商也提供了越來越豐富的通訊服務(wù)功能。不容置疑,Internet 已經(jīng)成為真正的信息高速公路。從實(shí)際工程應(yīng)用角度出發(fā),以計(jì)算機(jī)網(wǎng)絡(luò)原理為指導(dǎo),結(jié)合當(dāng)前網(wǎng)絡(luò)中的一些常用技術(shù),編程實(shí)現(xiàn)基于C/S 架構(gòu)的網(wǎng)絡(luò)聊天工具是切實(shí)可行的。

    目前,中國市場上的企業(yè)級(jí)即時(shí)通信工具主要包括:信鴿、視高科技的視高可視協(xié)同辦公平臺(tái)、263EM、群英CC2010、通軟聯(lián)合的GoCom、騰訊公司的RTX、IBM 的Lotus Sametime、點(diǎn)擊科技的GKE、中國互聯(lián)網(wǎng)辦公室的imo、中國移動(dòng)的企業(yè)飛信、華夏易聯(lián)的e-Link、擎旗的UcStar 等。相對于個(gè)人即時(shí)通信工具而言,企業(yè)級(jí)即時(shí)通信工具更加強(qiáng)調(diào)安全性、實(shí)用性、穩(wěn)定性和擴(kuò)展性。

    1.1 即時(shí)聊天的解決方案

    • socket:套接字,連接需要ip和端口,分為tcp和udp兩種形式
    • xmpp:xmpp + openfire + asmack

    1.2 常見協(xié)議

    1.3 常見的術(shù)語

    • xmpp:基于xml的可拓展協(xié)議.
    • jabber:xmpp的前身.
    • openfire:支持xmpp的開源服務(wù)器
    • smack.jar:對xmpp協(xié)議封裝.方便開發(fā)的jar包.
    • spark.exe:基于xmpp的pc客戶端;
    • asmack.jar:smack.jar的精簡版.專門針對android端開發(fā)

    2. 基本概念和原理

    2.1 常用的網(wǎng)絡(luò)通信協(xié)議

    TCP/IP:Transmission Control Protocol/Internet Protocol 的簡寫,中譯名為傳輸控制協(xié)議/因特網(wǎng)互聯(lián)協(xié)議,又名網(wǎng)絡(luò)通訊協(xié)議,是Internet 最基本的協(xié)議、Internet 國際互聯(lián)網(wǎng)絡(luò)的基礎(chǔ),由網(wǎng)絡(luò)層的IP 協(xié)議和傳輸層的TCP協(xié)議組成。TCP/IP 定義了電子設(shè)備如何連入因特網(wǎng),以及數(shù)據(jù)如何在它們之間傳輸?shù)臉?biāo)準(zhǔn)。協(xié)議采用了4 層的層級(jí)結(jié)構(gòu),每一層都呼叫它的下一層所提供的協(xié)議來完成自己的需求。通俗而言:TCP 負(fù)責(zé)發(fā)現(xiàn)傳輸?shù)膯栴},一有問題就發(fā)出信號(hào),要求重新傳輸,直到所有數(shù)據(jù)安全正確地傳輸?shù)侥康牡亍6鳬P 是給因特網(wǎng)的每一臺(tái)聯(lián)網(wǎng)設(shè)備規(guī)定一個(gè)地址。

    UDP:UDP 協(xié)議全稱是用戶數(shù)據(jù)報(bào)協(xié)議,在網(wǎng)絡(luò)中它與TCP 協(xié)議一樣用于處理數(shù)據(jù)包,是一種無連接的協(xié)議。在OSI 模型中,在第四層——傳輸層,處于IP 協(xié)議的上一層。UDP 有不提供數(shù)據(jù)包分組、組裝和不能對數(shù)據(jù)包進(jìn)行排序的缺點(diǎn),也就是說,當(dāng)報(bào)文發(fā)送之后,是無法得知其是否安全完整到達(dá)的。UDP 用來支持那些需要在計(jì)算機(jī)之間傳輸數(shù)據(jù)的網(wǎng)絡(luò)應(yīng)用。包括網(wǎng)絡(luò)視頻會(huì)議系統(tǒng)在內(nèi)的眾多的客戶/服務(wù)器模式的網(wǎng)絡(luò)應(yīng)用都需要使用UDP協(xié)議。UDP 協(xié)議從問世至今已經(jīng)被使用了很多年,雖然其最初的光彩已經(jīng)被一些類似協(xié)議所掩蓋,但是即使是在今天UDP 仍然不失為一項(xiàng)非常實(shí)用和可行的網(wǎng)絡(luò)傳輸層協(xié)議。

    TCP/IP 協(xié)議棧主要分為四層:應(yīng)用層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層,每層都有相應(yīng)的協(xié)議,如下圖:

    所謂的協(xié)議就是雙方進(jìn)行數(shù)據(jù)傳輸?shù)囊环N格式。

    2.2 TCP、UDP 特點(diǎn)對比

    TCP 協(xié)議是面向連接、保證高可靠性(數(shù)據(jù)無丟失、數(shù)據(jù)無失序、數(shù)據(jù)無錯(cuò)誤、數(shù)據(jù)無重復(fù)到達(dá))傳輸層協(xié)議。UDP 協(xié)議也是傳輸層協(xié)議,它是無連接,不保證可靠的傳輸層協(xié)議。

    2.3 TCP 三次握手過程

    1、請求端(通常稱為客戶)發(fā)送一個(gè)SYN 段指明客戶打算連接的服務(wù)器的端口,以及初始序號(hào)(ISN)
    2、服務(wù)器發(fā)回包含服務(wù)器的初始序號(hào)的SYN 報(bào)文段(報(bào)文段2)作為應(yīng)答。同時(shí),將確認(rèn)序號(hào)設(shè)置為客戶的ISN加1 以對客戶的SYN 報(bào)文段進(jìn)行確認(rèn)。

    TCPUDP
    面向連接面向非連接
    可靠的連接不可靠的連接
    速度慢速度快
    大文件、重要的數(shù)據(jù)等適合小數(shù)據(jù)、不重要

    3、客戶必須將確認(rèn)序號(hào)設(shè)置為服務(wù)器的ISN 加1 以對服務(wù)器的SYN 報(bào)文段進(jìn)行確認(rèn)(報(bào)文段3)這三個(gè)報(bào)文段完成連接的建立。這個(gè)過程也稱為三次握手(three-way handshake)。

    上面的過程如下圖所示:

    2.4 即時(shí)通訊形式

    直接通訊

    兩個(gè)不同客戶端之間不經(jīng)過服務(wù)器,直接通過網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)的交互。常用的p2p 技術(shù)就是直接通訊的形式。

    在線代理通訊

    一個(gè)客戶端發(fā)送的消息先發(fā)送到服務(wù)器,服務(wù)器接收到消息后再發(fā)送給指定的另外一個(gè)客戶端。QQ 的消息
    尤其是離線消息就是同在線代理的方式實(shí)現(xiàn)的。

    離線代理通訊

    一個(gè)客戶端發(fā)送消息給服務(wù)器,服務(wù)器存儲(chǔ)在數(shù)據(jù)庫中個(gè),當(dāng)另外一個(gè)客戶端上線后在發(fā)送過去。

    離線擴(kuò)展通訊

    一個(gè)客戶端發(fā)送消息給服務(wù)器,服務(wù)器通過郵件、短信等其他形式將消息發(fā)送給接收者。

    3. ServerSocket 和Socket

    3.1 使用Java 完成簡單的Socket 通信

    在Java 中Socket 可以理解為客戶端或者服務(wù)器端的一個(gè)特殊的對象,這個(gè)對象有兩個(gè)關(guān)鍵的方法,一個(gè)是getInputStream 方法,另一個(gè)是getOutputStream 方法。getInputStream 方法可以得到一個(gè)輸入流,客戶端的Socket對象上的getInputStream 方法得到的輸入流其實(shí)就是從服務(wù)器端發(fā)回的數(shù)據(jù)流。GetOutputStream 方法得到一個(gè)輸出流,客戶端Socket 對象上的getOutputStream 方法返回的輸出流就是將要發(fā)送到服務(wù)器端的數(shù)據(jù)流,(其實(shí)是一個(gè)緩沖區(qū),暫時(shí)存儲(chǔ)將要發(fā)送過去的數(shù)據(jù))。

    下面就讓我們寫一個(gè)簡單的Demo 來演示Socket 是如何使用的。

    建立服務(wù)器類

    服務(wù)類使用到的核心類的是ServerSocket。這里我們只需要建立一個(gè)Java Project 即可。

    public class IMServer {private static ServerSocket serverSocket;private static BufferedReader reader;public static void main(String[] args) {try {serverSocket = new ServerSocket(7788);/*** 等待接收客戶端連接進(jìn)來,該方法是線程阻塞的*/Socket accept = serverSocket.accept();/*** 獲取輸入流,用于接收客戶端發(fā)來的數(shù)據(jù)*/InputStream inputStream = accept.getInputStream();/*** 將字節(jié)輸入流轉(zhuǎn)化為字符輸出流*/reader = new BufferedReader(new InputStreamReader(inputStream));/*** 打印數(shù)據(jù)*/String tmp = null;while ((tmp = reader.readLine()) != null) {System.out.println(tmp);}} catch (Exception e) {e.printStackTrace();} finally {try {if (serverSocket != null) {serverSocket.close();}} catch (IOException e) {e.printStackTrace();}if (reader != null) {try {reader.close();} catch (IOException e) {e.printStackTrace();}}}}}

    建立客戶端類

    public class IMClient {private static Socket socket;private static BufferedWriter writer;/*** @param args*/public static void main(String[] args) {try {socket = new Socket("127.0.0.1", 7788);/*** 獲取輸出流*/OutputStream outputStream = socket.getOutputStream();writer = new BufferedWriter(new OutputStreamWriter(outputStream));writer.write("hello wo shi wzy!" + new Date().getTime());writer.close();} catch (IOException e) {e.printStackTrace();} finally {if (socket != null) {try {socket.close();} catch (IOException e) {e.printStackTrace();}}if (writer != null) {try {writer.close();} catch (IOException e) {e.printStackTrace();}}}}}

    在上面的代碼中我們僅僅實(shí)現(xiàn)了一個(gè)最簡單的服務(wù)器和客戶端,服務(wù)器啟動(dòng)起來后只能接受到一次消息,然后就關(guān)閉了。如果想讓服務(wù)器一直運(yùn)行,應(yīng)該通過死循環(huán)來處理不同的發(fā)送進(jìn)來的消息。

    Socket調(diào)試工具

    TCP/UDP Socket調(diào)試工具提供了TCP Server,TCP Client,UDP Server,UDP Client,UDP Group 五種Socket調(diào)試方案

    TCP

    手機(jī)作為Client,PC作為Server

    public class MyClientActivity extends Activity {private EditText mEditText = null;private Button connectButton = null;private Button sendButton = null;private TextView mTextView = null;private Socket clientSocket = null;private OutputStream outStream = null;private Handler mHandler = null;private ReceiveThread mReceiveThread = null;private boolean stop = true;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mEditText = (EditText) this.findViewById(R.id.edittext);mTextView = (TextView) this.findViewById(R.id.retextview);connectButton = (Button) this.findViewById(R.id.connectbutton);sendButton = (Button) this.findViewById(R.id.sendbutton);sendButton.setEnabled(false);// 連接按鈕監(jiān)聽connectButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubtry {// 實(shí)例化對象并連接到服務(wù)器clientSocket = new Socket("172.27.35.1", 60000);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}displayToast("連接成功!");// 連接按鈕使能connectButton.setEnabled(false);// 發(fā)送按鈕使能sendButton.setEnabled(true);mReceiveThread = new ReceiveThread(clientSocket);stop = false;// 開啟線程mReceiveThread.start();}});// 發(fā)送數(shù)據(jù)按鈕監(jiān)聽sendButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubbyte[] msgBuffer = null;// 獲得EditTex的內(nèi)容String text = mEditText.getText().toString();try {// 字符編碼轉(zhuǎn)換msgBuffer = text.getBytes("GB2312");} catch (UnsupportedEncodingException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}try {// 獲得Socket的輸出流outStream = clientSocket.getOutputStream();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {// 發(fā)送數(shù)據(jù)outStream.write(msgBuffer);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 清空內(nèi)容mEditText.setText("");displayToast("發(fā)送成功!");}});// 消息處理mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {// 顯示接收到的內(nèi)容mTextView.setText((msg.obj).toString());}};}// 顯示Toast函數(shù)private void displayToast(String s) {Toast.makeText(this, s, Toast.LENGTH_SHORT).show();}private class ReceiveThread extends Thread {private InputStream inStream = null;private byte[] buf;private String str = null;ReceiveThread(Socket s) {try {// 獲得輸入流this.inStream = s.getInputStream();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic void run() {while (!stop) {this.buf = new byte[512];try {// 讀取輸入數(shù)據(jù)(阻塞)this.inStream.read(this.buf);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 字符編碼轉(zhuǎn)換try {this.str = new String(this.buf, "GB2312").trim();} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}Message msg = new Message();msg.obj = this.str;// 發(fā)送消息mHandler.sendMessage(msg);}}}@Overridepublic void onDestroy() {super.onDestroy();if (mReceiveThread != null) {stop = true;mReceiveThread.interrupt();}}}

    手機(jī)作為Server,PC作為Client

    public class MyServerActivity extends Activity {private TextView ipTextView = null;private EditText mEditText = null;private Button sendButton = null;private TextView mTextView = null;private OutputStream outStream = null;private Socket clientSocket = null;private ServerSocket mServerSocket = null;private Handler mHandler = null;private AcceptThread mAcceptThread = null;private ReceiveThread mReceiveThread = null;private boolean stop = true;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);ipTextView = (TextView) this.findViewById(R.id.iptextview);mEditText = (EditText) this.findViewById(R.id.sedittext);sendButton = (Button) this.findViewById(R.id.sendbutton);sendButton.setEnabled(false);mTextView = (TextView) this.findViewById(R.id.textview);// 發(fā)送數(shù)據(jù)按鈕監(jiān)聽sendButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubbyte[] msgBuffer = null;// 獲得EditTex的內(nèi)容String text = mEditText.getText().toString();try {// 字符編碼轉(zhuǎn)換msgBuffer = text.getBytes("GB2312");} catch (UnsupportedEncodingException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}try {// 獲得Socket的輸出流outStream = clientSocket.getOutputStream();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {// 發(fā)送數(shù)據(jù)outStream.write(msgBuffer);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 清空內(nèi)容mEditText.setText("");displayToast("發(fā)送成功!");}});// 消息處理mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 0: {// 顯示客戶端IPipTextView.setText((msg.obj).toString());// 使能發(fā)送按鈕sendButton.setEnabled(true);break;}case 1: {// 顯示接收到的數(shù)據(jù)mTextView.setText((msg.obj).toString());break;}}}};mAcceptThread = new AcceptThread();// 開啟監(jiān)聽線程mAcceptThread.start();}// 顯示Toast函數(shù)private void displayToast(String s) {Toast.makeText(this, s, Toast.LENGTH_SHORT).show();}private class AcceptThread extends Thread {@Overridepublic void run() {try {// 實(shí)例化ServerSocket對象并設(shè)置端口號(hào)為7100mServerSocket = new ServerSocket(60000);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {// 等待客戶端的連接(阻塞)clientSocket = mServerSocket.accept();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}mReceiveThread = new ReceiveThread(clientSocket);stop = false;// 開啟接收線程mReceiveThread.start();Message msg = new Message();msg.what = 0;// 獲取客戶端IPmsg.obj = clientSocket.getInetAddress().getHostAddress();// 發(fā)送消息mHandler.sendMessage(msg);}}private class ReceiveThread extends Thread {private InputStream mInputStream = null;private byte[] buf;private String str = null;ReceiveThread(Socket s) {try {// 獲得輸入流this.mInputStream = s.getInputStream();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic void run() {while (!stop) {this.buf = new byte[512];// 讀取輸入的數(shù)據(jù)(阻塞讀)try {this.mInputStream.read(buf);} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}// 字符編碼轉(zhuǎn)換try {this.str = new String(this.buf, "GB2312").trim();} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}Message msg = new Message();msg.what = 1;msg.obj = this.str;// 發(fā)送消息mHandler.sendMessage(msg);}}}@Overridepublic void onDestroy() {super.onDestroy();if (mReceiveThread != null) {stop = true;mReceiveThread.interrupt();}}}

    UDP

    public class MainActivity extends Activity {private static String TAG = "CallActivity";private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {// 播放聲音initBeepSound();playBeepSoundAndVibrate();Log.i(TAG, "reciever_msg");String result = (String) msg.obj;System.out.println(result);tv_result.setText(result);};};private String ip;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODOsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ip = IpUtil.getIp(this);Toast.makeText(this, ip, Toast.LENGTH_LONG).show();System.out.println("ip:" + ip);tv_result = (TextView) findViewById(R.id.tv_result);}/*** 發(fā)送者*/public void send(View v) {new Thread() {@Overridepublic void run() {try {//1. 創(chuàng)建一個(gè)DatagramSocket對象DatagramSocket socket = new DatagramSocket(5678);//2. 創(chuàng)建一個(gè) InetAddress , 相當(dāng)于是地址,就是想要發(fā)送的ip地址InetAddress serverAddress = InetAddress.getByName("172.27.35.1");//3. 這是隨意發(fā)送一個(gè)數(shù)據(jù)String str = "來自android手機(jī)的問候";//4. 轉(zhuǎn)為byte類型byte data[] = str.getBytes("GBK");//5. 創(chuàng)建一個(gè)DatagramPacket 對象,并指定要講這個(gè)數(shù)據(jù)包發(fā)送到網(wǎng)絡(luò)當(dāng)中的哪個(gè)地址,以及端口號(hào)DatagramPacket pack = new DatagramPacket(data, data.length, serverAddress, 5678);//6. 調(diào)用DatagramSocket對象的send方法 發(fā)送數(shù)據(jù)socket.send(pack);} catch (SocketException e) {Log.i(TAG, "error");e.printStackTrace();} catch (UnknownHostException e) {Log.i(TAG, "error");e.printStackTrace();} catch (IOException e) {Log.i(TAG, "error");e.printStackTrace();}}}.start();}/*** 接收者* @param v*/public void receive(View v) {new Thread() {@Overridepublic void run() {// 執(zhí)行完畢后給handler發(fā)送一個(gè)空消息try {// 1. 創(chuàng)建一個(gè)DatagramSocket對象,并指定監(jiān)聽的端口號(hào)/\DatagramSocket socket = new DatagramSocket(5678);// 2. 創(chuàng)建一個(gè)byte數(shù)組用于接收byte data[] = new byte[1024];// 3. 創(chuàng)建一個(gè)空的DatagramPackage對象DatagramPacket pack = new DatagramPacket(data, data.length);// 4. 使用receive方法接收發(fā)送方所發(fā)送的數(shù)據(jù),同時(shí)這也是一個(gè)阻塞的方法while (true) {Log.i(TAG, "reciever_1");socket.receive(pack);Log.i(TAG, "reciever_2");// 5. 得到發(fā)送過來的數(shù)據(jù)// String result = new String(pack.getData(), pack.getOffset(), pack.getLength(),"GBK");String result = new String(pack.getData(), pack.getOffset(), pack.getLength());Message msg = new Message();msg.obj = result;handler.sendMessage(msg);Log.i(TAG, "sendmsg_1");}} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();Log.i(TAG, "error");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();Log.i(TAG, "error");}}}.start();}@Overrideprotected void onDestroy() {super.onDestroy();}// 播放聲音private static final float BEEP_VOLUME = 0.10f;private MediaPlayer mediaPlayer;private void initBeepSound() {if (mediaPlayer == null) {setVolumeControlStream(AudioManager.STREAM_MUSIC);mediaPlayer = new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setOnCompletionListener(beepListener);AssetFileDescriptor file = getResources().openRawResourceFd(R.raw.beep);try {mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());file.close();mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);mediaPlayer.prepare();} catch (IOException e) {mediaPlayer = null;}}}private void playBeepSoundAndVibrate() {if (mediaPlayer != null) {mediaPlayer.start();}// 震動(dòng)Vibrator mVibrator = (Vibrator) getApplication().getSystemService(Service.VIBRATOR_SERVICE);mVibrator.vibrate(2000);long[] pattern = { 0, 100, 200, 100, 200 };mVibrator.vibrate(pattern, -1);}private final OnCompletionListener beepListener = new OnCompletionListener() {public void onCompletion(MediaPlayer mediaPlayer) {mediaPlayer.seekTo(0);}};// 退出提醒private long exitTime;private TextView tv_result;@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {if ((System.currentTimeMillis() - exitTime) > 2000) {Toast.makeText(getApplicationContext(), "再按一次退出" + getResources().getString(R.string.app_name),Toast.LENGTH_SHORT).show();exitTime = System.currentTimeMillis();} else {finish();}return true;}return super.onKeyDown(keyCode, event);} }

    IpUtil.java

    public class IpUtil {/*** 獲取手機(jī)ip* * @return*/public static String getLocalIpAddress() {try {for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {NetworkInterface intf = en.nextElement();for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {InetAddress inetAddress = enumIpAddr.nextElement();if (!inetAddress.isLoopbackAddress()) {String ip = inetAddress.getHostAddress().toString();System.out.println("getLocalIpAddressIP:"+ip);return ip;}}}} catch (SocketException ex) {Log.e("ifo", ex.toString());}return "";}public static String getIp(Activity activity) {WifiManager wifiManager = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE);WifiInfo wifiInfo = wifiManager.getConnectionInfo();int ipAddress = wifiInfo.getIpAddress();// 格式化IP address,例如:格式化前:1828825280,格式化后:192.168.1.109String ip = String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff));System.out.println("getIpIP:"+ip);return ip;}}

    總結(jié)

    以上是生活随笔為你收集整理的即时通讯基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美在线看 | 中文字幕免费一区二区 | 亚洲色图一区二区三区 | 看a网站 | 亚洲av无码乱码在线观看富二代 | 女裸全身无奶罩内裤内衣内裤 | 插插插日日日 | 日韩成人性视频 | 国产一级二级在线观看 | 国产人妖一区二区三区 | 免费在线观看一区二区三区 | 又色又爽又黄无遮挡的免费视频 | jizzjizz在线观看| 色站在线 | 精品一区二区三区毛片 | 国产精品一区二区三区在线看 | 国产三级在线观看完整版 | 成人激情综合 | 熟女视频一区二区三区 | 性视频播放免费视频 | 色婷婷av一区二区三 | 黄色永久视频 | 欧美亚洲国产一区 | 午夜一级大片 | 午夜精品久久久久久99热 | 欧美特级黄色片 | 午夜伦情| 最全aⅴ番号库 | 91av视频免费观看 | 一区二区欧美精品 | 成人亚洲精品久久久久软件 | 欧洲av一区二区 | 国产夫妻av | 天天弄天天操 | 欧美操穴视频 | 欧美岛国国产 | 亚洲热在线视频 | 2019天天操 | av在线免费播放网站 | 蜜臀av首页 | 激情一区二区三区 | 五十路在线 | 日本一区二区三区在线观看 | 麻豆黄色网 | 日本青草视频 | 亚洲综合色网站 | 亚洲色图偷拍视频 | hitomi一区二区三区精品 | 邻居校草天天肉我h1v1 | 99自拍视频在线观看 | 五月婷婷网 | 午夜精品视频一区 | 久久久久久久久久免费视频 | 黄色成人一级片 | 日本最新中文字幕 | 久久九九免费视频 | 国产第九页 | 亚洲羞羞| 男朋友是消防员第一季 | 中文字幕第六页 | 男人插女人免费视频 | 成人精品一区二区三区中文字幕 | 亚洲AV无码精品自拍 | 亚洲免费久久 | 日韩欧美aⅴ综合网站发布 国产成人一区二区三区小说 | 成人欧美一区二区三区白人 | 精品中文字幕一区二区 | 亚洲精品h| 影音先锋欧美在线 | 涩涩小网站 | 新x8x8拨牐拨牐永久免费影库 | 操你妹影院| 国产一区不卡在线观看 | 开心激情网站 | 亚洲精品激情 | 青青青视频在线播放 | 狠狠干在线观看 | 白白色在线播放 | 制服av网 | 亚洲一区精品视频在线观看 | 色就是色亚洲色图 | 91在线超碰 | 亚洲va国产va天堂va久久 | 欧美成人女星 | 99视频在线精品 | 丰满少妇被猛烈进入一区二区 | 日韩在线播放av | 日韩毛片| 精品在线视频免费 | 丝袜美腿亚洲综合 | 少妇光屁股影院 | 九九色九九 | 天天搞天天搞 | 国产宾馆自拍 | 99热在线这里只有精品 | 久久久久久久999 | 国产视色 | 亚洲视频123 | 91久久精品一区二区别 |