Android实现TCP客户端
Android實(shí)現(xiàn)TCP客戶端
1.添加相關(guān)權(quán)限,使得android app可以訪問網(wǎng)絡(luò)
在AndroidManiffest.xml中添加
<uses-permission android:name="android.permission.INTERNET"/>2.socket的連接
由于android平臺(tái)的限制,與網(wǎng)絡(luò)相關(guān)的操作只能在子線程中進(jìn)行,所以這里我們單獨(dú)建立一個(gè)線程用于socket的連接
//子線程中進(jìn)行網(wǎng)絡(luò)相關(guān)操作class connectthread extends Thread {OutputStream outputStream=null;InputStream inputStream=null;@Overridepublic void run() {//連接try {socket=new Socket(a, b);runOnUiThread(new Runnable()//不允許其他線程直接操作組件,用提供的此方法可以{public void run(){// TODO Auto-generated method stubToast.makeText(MainActivity.this,"連接成功",Toast.LENGTH_SHORT).show();}});} catch (UnknownHostException e) {// TODO Auto-generated catch blockrunOnUiThread(new Runnable()//不允許其他線程直接操作組件,用提供的此方法可以{public void run(){// TODO Auto-generated method stubToast.makeText(MainActivity.this,"連接失敗",Toast.LENGTH_SHORT).show();}});e.printStackTrace();}catch (IOException e) {e.printStackTrace();runOnUiThread(new Runnable()//不允許其他線程直接操作組件,用提供的此方法可以{public void run(){// TODO Auto-generated method stubToast.makeText(MainActivity.this,"連接失敗",Toast.LENGTH_SHORT).show();}});} }socket=new socket(a,b)這一方法可以建立一個(gè)tcp連接,其中,a為ip地址,b為端口號(hào)
如果連接成功,我們及通過Toast在屏幕中顯示“連接成功”,若連接失敗,則會(huì)轉(zhuǎn)到異常中,我們通過Toast顯示“連接失敗”。
3.通過輸出流發(fā)送消息
在子線程中添加以下代碼,獲取socket的輸出流對(duì)象
并通過輸出流對(duì)象的write()方法向服務(wù)器發(fā)送“123”
以上就是最簡單的消息發(fā)送,下面我們通過edittext獲取輸入的內(nèi)容,并將輸入的內(nèi)容發(fā)送給服務(wù)器
//發(fā)送send.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//子線程中進(jìn)行網(wǎng)絡(luò)操作new Thread(new Runnable() {@Overridepublic void run() {if(socket!=null){try {String text=out.getText().toString();lianjie.outputStream.write(text.getBytes());} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();}catch (IOException e) {e.printStackTrace();}}else{runOnUiThread(new Runnable()//不允許其他線程直接操作組件,用提供的此方法可以{public void run(){// TODO Auto-generated method stubToast.makeText(MainActivity.this,"請(qǐng)先建立連接",Toast.LENGTH_SHORT).show();}});}}}).start();}});需要注意的是,發(fā)送的操作需要在子線程中進(jìn)行,所以這里我又建立了一個(gè)線程來進(jìn)行發(fā)送的操作,在線程中獲取socket的輸出流對(duì)象即可進(jìn)行內(nèi)容的發(fā)送。
在這里我加了一個(gè)提示信息,如果socket為空的話,則提示“請(qǐng)先建立連接”。
4.通過輸入流獲取消息
在子線程中建立一個(gè)死循環(huán),時(shí)刻監(jiān)聽輸入流,讀取服務(wù)器發(fā)送來的消息
try{while (true){final byte[] buffer = new byte[1024];//創(chuàng)建接收緩沖區(qū)inputStream = socket.getInputStream();final int len = inputStream.read(buffer);//數(shù)據(jù)讀出來,并且返回?cái)?shù)據(jù)的長度runOnUiThread(new Runnable()//不允許其他線程直接操作組件,用提供的此方法可以{public void run(){// TODO Auto-generated method stubreceive.append(new String(buffer,0,len)+"\r\n");}});}}catch (IOException e) {}5.測試結(jié)果
客戶端
服務(wù)器
經(jīng)過測試,服務(wù)器和客戶端之間可以正常的發(fā)送和接收信息。
6.源代碼
xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><EditTextandroid:id="@+id/ip"android:layout_width="wrap_content"android:layout_height="wrap_content"android:hint="ip"/><EditTextandroid:id="@+id/port"android:layout_width="wrap_content"android:layout_height="wrap_content"android:hint="port"/><EditTextandroid:id="@+id/out"android:layout_width="wrap_content"android:layout_height="wrap_content"android:hint="請(qǐng)輸入要發(fā)送的內(nèi)容"/><Buttonandroid:id="@+id/connect"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="連接"/><Buttonandroid:id="@+id/send"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="發(fā)送"/><TextViewandroid:id="@+id/receive"android:layout_width="wrap_content"android:layout_height="wrap_content"/></LinearLayout>Mainactivity
public class MainActivity extends AppCompatActivity {String a;int b;connectthread lianjie;TextView receive;Socket socket=null;Button connect;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);EditText ip=findViewById(R.id.ip);EditText port=findViewById(R.id.port);EditText out=findViewById(R.id.out);receive=findViewById(R.id.receive);connect=findViewById(R.id.connect);Button send=findViewById(R.id.send);connect.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {a=ip.getText().toString();String c=port.getText().toString();if("".equals(a)||"".equals(c)){Toast.makeText(MainActivity.this,"請(qǐng)輸入ip和端口號(hào)",Toast.LENGTH_SHORT).show();}else{b=Integer.valueOf(c);lianjie=new connectthread();lianjie.start();}}});//發(fā)送send.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//子線程中進(jìn)行網(wǎng)絡(luò)操作new Thread(new Runnable() {@Overridepublic void run() {if(socket!=null){try {String text=out.getText().toString();lianjie.outputStream.write(text.getBytes());} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();}catch (IOException e) {e.printStackTrace();}}else{runOnUiThread(new Runnable()//不允許其他線程直接操作組件,用提供的此方法可以{public void run(){// TODO Auto-generated method stubToast.makeText(MainActivity.this,"請(qǐng)先建立連接",Toast.LENGTH_SHORT).show();}});}}}).start();}});}//子線程中進(jìn)行網(wǎng)絡(luò)相關(guān)操作class connectthread extends Thread {OutputStream outputStream=null;InputStream inputStream=null;@Overridepublic void run() {//連接try {socket=new Socket(a, b);runOnUiThread(new Runnable()//不允許其他線程直接操作組件,用提供的此方法可以{public void run(){// TODO Auto-generated method stubToast.makeText(MainActivity.this,"連接成功",Toast.LENGTH_SHORT).show();}});} catch (UnknownHostException e) {// TODO Auto-generated catch blockrunOnUiThread(new Runnable()//不允許其他線程直接操作組件,用提供的此方法可以{public void run(){// TODO Auto-generated method stubToast.makeText(MainActivity.this,"連接失敗",Toast.LENGTH_SHORT).show();}});e.printStackTrace();}catch (IOException e) {e.printStackTrace();runOnUiThread(new Runnable()//不允許其他線程直接操作組件,用提供的此方法可以{public void run(){// TODO Auto-generated method stubToast.makeText(MainActivity.this,"連接失敗",Toast.LENGTH_SHORT).show();}});}if(socket!=null){//獲取輸出流對(duì)象try {outputStream=socket.getOutputStream();outputStream.write(123);} catch (IOException e) {e.printStackTrace();}try{while (true){final byte[] buffer = new byte[1024];//創(chuàng)建接收緩沖區(qū)inputStream = socket.getInputStream();final int len = inputStream.read(buffer);//數(shù)據(jù)讀出來,并且返回?cái)?shù)據(jù)的長度runOnUiThread(new Runnable()//不允許其他線程直接操作組件,用提供的此方法可以{public void run(){// TODO Auto-generated method stubreceive.append(new String(buffer,0,len)+"\r\n");}});}}catch (IOException e) {}}}; }}7.參考文章
Android 一步步實(shí)現(xiàn)TCP客戶端
Android網(wǎng)絡(luò)編程之–Socket編程
android 之TCP客戶端編程
Android Studio TCP客戶端實(shí)現(xiàn)
Android的SocketTCP客戶端發(fā)送信息
總結(jié)
以上是生活随笔為你收集整理的Android实现TCP客户端的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 获取系统信息1——linux系统中的时间
- 下一篇: 27款优秀的Android逆向工程工具