首页 >> 大全

Android-socket的基本使用,发送文字和图片以及心跳

2023-12-22 大全 25 作者:考证青年

要求发送的消息的格式是,8个字节的消息长度+消息体

这里写图片描述

因为需要8个字节,所以消息长度决定用long

如果需要4个字节,可以用int。

手机客户端接收服务器的文字消息 服务端

服务端定义好端口号,开启以一个,写入文字消息:

public class Service {private static Socket socket;//定义端口号private static final int POST = 30000;public static void main(String[] args) {try {//发送的内容sendMsg("来自服务器的问候");} catch (IOException e) {e.printStackTrace();}}public static void sendMsg(String msg) throws IOException {System.out.println("开始连接");//创建socket服务端口是30000,并等待连接ServerSocket serverSocket = new ServerSocket(POST);Socket socket = serverSocket.accept();//获取输出流DataOutputStream out = new DataOutputStream(socket.getOutputStream());sendTextMsg(out, msg);out.close();socket.close();serverSocket.close();System.out.println("通讯结束");}public static void sendTextMsg(DataOutputStream out, String msg) throws IOException {//先写长度,就是消息体的字节数,long刚好8个字节  out.writeLong(msg.getBytes().length);//写入消息out.write(msg.getBytes());}
}

客户端,接收消息

客户端首先要跟服务器进行连接,然后才能进行通讯。

连接需要网络权限:

<uses-permission android:name="android.permission.INTERNET"/>

因为属于网络通讯,所以连接也不能放在主线程中,否则会报错

这里写图片描述

运行测试

先运行服务端,会发现程序没有一次执行完,在阻塞着等待连接

这里写图片描述

这时点击app中的接收按钮,日志中会打印接收到的信息

长度为24,消息内容为“来自服务器的问候”。

因为在utf-8中一个汉字是3个字节,所以8个汉字的消息长度是24字节。

这是看服务器端的打印:

这里写图片描述

发现服务端也正常执行完毕了。

手机客户端向服务端发送文字消息 服务端接收消息

public class Service {private static Socket socket;//定义端口号private static final int POST = 30000;public static void main(String[] args) {try {//接收消息getMsg();} catch (IOException e) {e.printStackTrace();}}public static void getMsg() throws IOException {System.out.println("开始连接");ServerSocket serverSocket = new ServerSocket(POST);Socket socket = serverSocket.accept();//获取输入流,通过这个流来读取消息DataInputStream input = new DataInputStream(socket.getInputStream());//接收文字消息getTextMsg(input);input.close();socket.close();serverSocket.close();System.out.println("通讯结束");}public static String getTextMsg(DataInputStream input) throws IOException {//一样先读长度,再根据长度读消息long len = input.readLong();System.out.println("len = " + len);byte[] bytes = new byte[(int) len];input.read(bytes);String msg = new String(bytes);System.out.println("msd = " + msg);return msg;}
}

客户端发送消息

<Button
        android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="发送!"android:onClick="send"/>

public void send(View view) {new Thread(new Runnable() {@Overridepublic void run() {Socket socket;try {//建立连接socket = new Socket(host, post);//获取输出流,通过这个流发送消息DataOutputStream out = new DataOutputStream(socket.getOutputStream());//发送文字消息sendTextMsg(out,"来自手机客户端的消息");out.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}).start();}
public void sendTextMsg(DataOutputStream out, String msg) throws IOException {byte[] bytes = msg.getBytes();long len = bytes.length;//先发送长度,在发送内容out.writeLong(len);out.write(bytes);}

运行测试

先运行服务端,也会停留着这个界面等待连接:

这里写图片描述

然后点击客户端的发送按钮,这是服务端会变成下面这样,完成这次消息的通讯

这里写图片描述

手机客户端想服务端发送图片 服务端接收图片,并保存到本地

在上面的()方法中,将(input);改为(input);

下面是(input);方法:

public static void getImgMsg(DataInputStream input) throws IOException {//同样是先读长度long len = input.readLong();System.out.println("len = " + len);byte[] bytes = new byte[(int) len];//然后在读这个长度的字节到字节数组input.readFully(bytes);//将独到的内容保存为文件到本地File file = new File("/Users/xxx/" + len + ".png");FileOutputStream fileOutputStream = new FileOutputStream(file);fileOutputStream.write(bytes);System.out.println("ok");
}

客户端发送图片

<Button
    android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="200dp"android:onClick="sendImg"android:text="发送图片" />

运行测试

还是先开启服务端,服务器变成:

这里写图片描述

然后点击app的发送图片按钮,app中打印日志:

说明发送的图片的长度是11418个字节,大致换算大小是11k。

_心跳图文字符号_发送心跳信息

然后看服务端的日志:

这里写图片描述

接收到的长度也是11418,并且保存到了文件,

这里写图片描述

关于心跳包

上面的例子中,每发送一次之后就把链接关闭了:

out.close();
socket.close();
serverSocket.close();

心跳其实就是定期向服务端发送一个小数据,比如0.

让服务器知道这个链接还有用,不用关闭。

简单实现起来就是客户端通过一个无限循环,不停地向服务端发送消息,服务端通过一个无限循环不停地接收消息,都不关闭这个链接就行了。

服务端

public static void main(String[] args) {try {System.out.println("开始接收信息");ServerSocket serverSocket = new ServerSocket(POST);socket = serverSocket.accept();DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());new Thread(new Runnable() {@Overridepublic void run() {while (true) {try {long len = 0;len = dataInputStream.readLong();System.out.println("len = " + len);byte[] bytes = new byte[(int) len];dataInputStream.readFully(bytes);String s = new String(bytes);System.out.println("data = " + s);} catch (IOException e) {e.printStackTrace();isConnect = false;}}}}).start();} catch (IOException e) {e.printStackTrace();}}

客户端,一秒发送一次消息

try {//建立一次链接socket = new Socket(host,post);outputStream = new DataOutputStream(socket.getOutputStream());inputStream = new DataInputStream(socket.getInputStream());
} catch (IOException e) {e.printStackTrace();
}
Log.i(TAG, "run: 开始循环发送发送心跳");
//一秒发送一个0,
while (true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}Log.i(TAG, "run: 发送心跳0");try {outputStream.writeLong("0".getBytes().length);outputStream.write("0".getBytes());} catch (IOException e) {e.printStackTrace();isConnect = false;}
}

运行测试

先运行服务端:

这里写图片描述

然后点击发送心跳的按钮,app的日志中打印:

这里写图片描述

在服务端的日志中可以看到:

这里写图片描述

一秒一次

_发送心跳信息_心跳图文字符号

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了