Android Studio TCP客户端实现
最近在做一个机器人的项目,需要用到TCP通讯这个东西。需要在手机做一个客户端,然后上去网上查了巨久巨多代码,为了避免让有需要的人少走弯路,就做一篇博文来推一下自己的做法,如果各位大大们有什么好的建议,也希望各位可以在评论区写下高见抑或是邮箱到1262706641@qq.com。
首先是布局文件的代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<EditText
android:id="@+id/ip"
android:layout_width="280dp"
android:layout_height="50dp"
android:background="#7CB342"
android:hint="IP:"
android:textColor="#ffffff"
/>
<EditText
android:id="@+id/port"
android:layout_width="match_parent"
android:layout_height="50dp"
android:hint="端口:"
android:background="#C0CA33"
android:layout_toRightOf="@id/ip"
android:inputType="number"
/>
<Button
android:id="@+id/connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/port"
android:text="连接服务器"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<TextView
android:id="@+id/receive"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#00ACC1"
android:textColor="#FFFFFF"
android:hint="接收区"
android:textSize="18sp"
android:gravity="center_horizontal"
/>
<EditText
android:id="@+id/send"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#3949AB"
android:hint="发送:"
android:textColor="#ffffff"
android:layout_below="@id/receive"/>
<Button
android:id="@+id/btn_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送"
android:layout_below="@+id/send"
/>
</RelativeLayout>
</RelativeLayout>
为了更方便以后的维护和迭代,我将发送模块、连接接收模块放在了不同的线程之中。
接下来先来看看最简单的 发送线程 代码。
//线程名:Send
public class Send extends Thread {
private String send;
private OutputStream outputStream;
private InputStream inputStream;
private String ip;
private int port;
public Send(String msg,int port,String ip) {
this.send = msg;
this.ip = ip;
this.port = port;
}
@Override
public void run() {
try {
Socket socket = new Socket(ip,port);
send="客户端发来:"+send;
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
outputStream.write((send+"\n").getBytes("utf-8"));
outputStream.flush();
Log.v("AndroidChat","发送成功:"+send);
}
catch (Exception e){
Log.v("AndroidChat","发送失败:"+send+"error"+e.getMessage());
e.printStackTrace();
}
}
Socket,套接字。利用这个建立和服务器之间的连接,会用就行,想深入了解去看其他大大的详解,这里不做赘述。
(这里插入一些题外话,无论代码有多长,建议各位都应当逐个函数的输入,复制粘贴只会走更多弯路。)
接下来是发送接收线程的代码:
package com.example.tcptext;
import android.util.Log;
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
import java.net.Socket;
//线程名:ConnectThread
public class ConnectThread extends Thread {
//Socket msg = null;//定义socket
private OutputStream out_ip=null;//定义输出流(ip)
OutputStream outputStream=null;
private InputStream inputStream;
private StringBuffer stringBuffer;
private String ip;
private int port;
private Receive receive;
private String string;
private boolean isRun = true;
private MainActivity.Receive re;
public ConnectThread(String ip, int port, MainActivity.Receive re) {
this.ip = ip;
this.port = port;
this.re = re;
}
@Override
public void run(){
Socket so = null;
try {
so = new Socket(ip, port);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": Hello");
try {
inputStream = so.getInputStream();
out_ip = so.getOutputStream();
Log.v("AndroidChat","开始连接服务器:"+ip+"/"+port);
sleep(1000);
}
catch (IOException | InterruptedException e) {
Log.v("AndroidChat","连接服务器失败"+e.getMessage());
e.printStackTrace();
return;
}
Log.v("AndroidChat","成功连接上服务器");
/*
下面是接收模块,你可以尝试探究如何将这个模块放在接收线程中。
*/
try {
inputStream = so.getInputStream();
final byte[] buffer = new byte[1024];
final int len = inputStream.read(buffer);
System.out.println(new String(buffer,0,len));
Log.v("AndroidChat","接收成功:"+new String(buffer,0,len));
string = new String(buffer,0,len);
re.setString(string);
//上下两行会和MainActivity关联,是回调在显示屏的关键步骤。
MainActivity.callback();
System.out.println(new String(buffer,0,len));
} catch (IOException e) {
e.printStackTrace();
}
}
}
最后是核心模块(MainActivity)
package com.example.tcptext;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button mBtn_send;
private Button mBtn_connect;
private EditText mEt_send;
private static TextView mTv_recv;
private String ip;
private int port;
private String msg;
private ConnectThread ct;
private Send send;
private Handler handler;
static Receive re = new Receive();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTv_recv = findViewById(R.id.receive);
mBtn_connect = findViewById(R.id.connect);
mBtn_send = findViewById(R.id.btn_1);
final EditText mEt_ip = this.findViewById(R.id.ip);
final EditText mEt_port = this.findViewById(R.id.port);
final EditText mEt_send = this.findViewById(R.id.send);
/*
设置一个点击事件用以连接线程
*/
mBtn_connect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ip = mEt_ip.getText().toString();//获取输入的ip
port = Integer.parseInt(mEt_port.getText().toString());//获取输入的端口号
ct = new ConnectThread(ip, port, re);//创建一个线程来处理消息的收发
ct.start();
}
});
/*
设计一个点击事件用以发送消息
*/
mBtn_send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
msg = mEt_send.getText().toString();
send = new Send(msg, port, ip);
send.start();
}
});
}
/*
这里是和连接接收线程中的 re.setString(string) 联动的,自己理解一下怎么走在脑子里面走一次就差不多了。
*/
static class Receive{
private String string;
public String getString(){
return string;
}
public void setString(String s){
this.string = s;
}
}
/*
下面的callback和连接接收线程中的 MainActivity.callback() 关联,线程运行到那一步后结束回到MainActivity中。
*/
public static void callback(){
System.out.println("连接线程执行结束");
mTv_recv.setText(re.getString());//这里是将接收到的文字显示在接收框内。
}
}
注意:
1.这里的点击按钮必须要输入好IP和端口号否则会闪退,我也不知道是什么原因,有哪位大大知道的,麻烦说一下。
2.每次连接接收完信息后都要点击一次连接服务器或者发送一条消息。各位可以一起探讨一下如何重新开启线程,反正我又百年不用Java,这个问题就留给各位了,哈哈哈。
最后,我分享一下我做这个程序的具体思路。零基础的朋友可以参照一下思路来遨游博海:
1.找到两个标准的TCP应用。这很关键,你必须得有标准的应用来测试才知道这是好的还是坏的。
2.善于利用 System.out.println(“哔哩吧啦”); 这个东西能很好的帮助你检查代码运行到什么地方。
3.将整个应用开发分成三个模块:连接服务器模块,发送信息模块,接收信息模块。每个模块还能再细分步骤:1.固定信息的传递(如连接模块就是固定IP和端口号);2.随机信息的传递。
4.优化你的界面,优化代码,做成自己理想的样子。
PS:1.我这里的函数回调是参照网上的一些博文做出的这里放一下链接:
https://blog.csdn.net/weixin_43475124/article/details/83930436?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159499807219195265934921%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159499807219195265934921&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v3~pc_rank_v3-2-83930436.pc_ecpm_v3_pc_rank_v3&utm_term=Java+%E5%88%A9%E7%94%A8%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E7%BA%BF%E7%A8%8B%E6%95%B0%E6%8D%AE%E4%BC%A0%E9%80%92
2.之后我会创一个Github账号将源码放出来,以便和大家一起学习交流。
3.这里用到的两个标准软件:PC端:TCPCOM android端:TCP连接
最后希望大家一起加油!用心攻破每个难题!
本文地址:https://blog.csdn.net/weixin_48848716/article/details/107429683
上一篇: 按摩足三里抗衰老
下一篇: 高通携手“金耳朵” 打造全新音频编解码器
推荐阅读
-
Android Studio 使用ViewPager + Fragment实现滑动菜单Tab效果 --简易版
-
实现Android studio设置自动导包及自动导包快捷键
-
Android实现客户端语音动弹界面实例代码
-
Android Studio实现标题栏和状态栏的隐藏
-
Android Studio 实现将support库改成Androidx
-
Android Studio 实现九宫格功能
-
详解Android Studio实现用户登陆界面demo(xml实现)
-
Android studio怎么实现github项目托管?
-
Android Studio实现发短信功能
-
C语言学习之Linux下TCP服务器与客户端的实现