1. UDP

(1)访问网络必须添加权限,访问网络必须添加权限,访问网络必须添加权限,重要的事情说三遍。

(2)简述

UDP协议是面向报文的,简单地说,利用UDP访问网络的步骤就是“寄快递”:通过DatagramPacket(快件)把数据和地址打包,然后用DatagramSocket(你)进行数据报的收发,至于中途是怎么传送,那就是快递员的事了,不归我们管(也因此,UCP的传输是不可靠的,可能会出现丢包的情况,跟某些快递简直一毛一样)。

InetAddress:记录访问的host等信息。

DatagramPacket:包装数据和访问地址,相当于一个快件。

DatagramSocket:用于发送和接收数据报,相当于快件的寄件人和收件人。

(3)简单示例

String serverIp = "111.111.111.11"; // 访问主机ip
InetAddress address = InetAddress.getByName(serverIp);
DatagramSocket socket = new DatagramSocket(8888); // 根据需要可在实例化时指定端口号 // 网络操作不能在UI线程进行
new Thread() {
@Override
public void run() {
try {
// 发送数据
String msg = "hello";
byte[] msgBytes = msg.getBytes();
DatagramPacket packet = new DatagramPacket(msgBytes, msgBytes.length, mAddress, mPort);
mSocket.send(packet); // 接收数据
byte[] returnMsgBytes = new byte[1024];
DatagramPacket returnPacket = new DatagramPacket(returnMsgBytes, returnMsgBytes.length, mAddress, mPort);
// receive()方法是阻塞的,会一直等待接收到包
mSocket.receive(returnPacket); String serverMsg = new String(returnPacket.getData(), 0, returnMsgBytes.length);
Log.d("test", serverMsg); } catch (IOException e) {
e.printStackTrace();
}
}
}.start();

从例子里我们可以看到,使用UDP就是打包数据、收发数据包这两步。

2. TCP

(1)还是权限,别忘了

(2)简述

与UDP不同,TCP是面向连接的,通过Socket对象创建连接,拿到一个输入流和一个输出流,然后再关闭连接前,可以一直发送与接收数据。

过程类似打电话,首先你得输入对方的电话号码(访问地址),然后拨通电话(创建连接通道),然后你说话(发送数据),或者听对方说话(接收数据),最后挂断电话(关闭连接)。

TCP创建连接时会经过三次握手,而断开连接时经过四次挥手。

(3)简单示例

try {
// 创建连接
Socket socket = new Socket("111.111.111.11", 8888); // 访问地址111.111.111.11:8888
// 拿到输入流(电话听筒)、输出流(电话话筒)
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream(); final BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream)); // 接收数据
new Thread() {
@Override
public void run() {
try {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start(); // 发送数据
String line = "test";
bw.write(line);
bw.newLine();
bw.flush(); } catch (IOException e) {
e.printStackTrace();
}

可以看到,与UDP不同,TCP是创建连接后,在断开连接前都可以直接通过输入输出流传输数据,不需要另外将数据打包。

(4)在安卓中应用

Activity:

public class TCPActivity extends AppCompatActivity {

    // 发送消息的按钮
private Button mSendBtn;
// 输入框
private EditText mMsgEt;
// 显示消息内容的文本框
private TextView mContentTv; private TCPClientBiz mBiz = new TCPClientBiz();
private boolean isConnected = false; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initView();
initEvent(); mBiz.connect(new TCPClientBiz.OnConnectedListener() {
@Override
public void onSucceed() {
// 连接成功
isConnected = true;
}
});
} private void initView() {
mSendBtn = findViewById(R.id.send_btn);
mMsgEt = findViewById(R.id.msg_et);
mContentTv = findViewById(R.id.content_tv);
} private void initEvent() {
mSendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final String msg = mMsgEt.getText().toString().trim();
if (!msg.isEmpty()) {
if (isConnected) {
mMsgEt.setText("");
// 发送消息
mBiz.send(msg);
}
}
}
}); // 接收服务器的消息
mBiz.setOnReceivedListener(new TCPClientBiz.OnReceivedListener() {
@Override
public void onReceived(String serverMsg) {
mContentTv.append(formatMsg(serverMsg));
} @Override
public void onError(Exception e) {
Toast.makeText(TCPActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} private String formatMsg(String msg) {
return msg + "\n";
}
}

业务类:

public class TCPClientBiz {

    private InputStream inputStream;
private OutputStream outputStream; private Handler handler = new Handler(Looper.getMainLooper()); // 异步连接,所以需要一个回调,告知已经连接成功
public void connect(final OnConnectedListener onConnectedListener) {
new Thread() {
@Override
public void run() {
try {
Socket socket = new Socket("169.254.165.37", 9999);
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
onConnectedListener.onSucceed(); while (true) {
// 不断接收服务器消息
receive();
} } catch (IOException e) {
e.printStackTrace();
}
}
}.start();
} private void receive() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
final String line;
if ((line = br.readLine()) != null) {
handler.post(new Runnable() {
@Override
public void run() {
if (onReceivedListener != null) {
onReceivedListener.onReceived(line);
}
}
});
}
} catch (final IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
if (onReceivedListener != null) {
onReceivedListener.onError(e);
}
}
});
}
} public void send(final String msg) {
new Thread() {
@Override
public void run() {
try {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
bw.write(msg);
bw.newLine();
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
} private OnReceivedListener onReceivedListener; public void setOnReceivedListener(OnReceivedListener onReceivedListener) {
this.onReceivedListener = onReceivedListener;
} // 接收消息接口
public interface OnReceivedListener { void onReceived(String serverMsg); void onError(Exception e);
} // 连接成功接口
public interface OnConnectedListener {
void onSucceed();
}
}

在安卓中运用需要注意一些点:第一,连接是异步,要添加回调,否则可能导致空指针异常;第二,网络操作中老生常谈的问题,UI操作注意不要在子线程中。

Android中的Socket的更多相关文章

  1. Android中基于Socket的网络通信

    1. Socket介绍 2. ServerSocket的建立与使用 3. 使用ServerSocket建立聊天服务器-1 4. 使用ServerSocket建立聊天服务器-2 5. 在Android中 ...

  2. 34、Android中基于Socket的网络通信(一)

    Socket又称”套接字”,应用程序通常通过”套接字”向网络发出请求或者应答网络请求. 在java中,Socket和ServerSocket类库位于java.net包中,ServerSocket用于服 ...

  3. android中利用Socket实现手机客户端与PC端进行通信

    1. 项目截图

  4. Android中的socket本地通讯框架

    一.先分析Native层: 1.C++基类SocketListener: class SocketListener {     int mSock;     const char *mSocketNa ...

  5. Android 网络编程 Socket Http

    前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net        ...

  6. 在android 中开发java.net.SocketException: socket failed: EACCES (Permission denied) 报错

    在android中下载文件,写好下载文件的代码后需要配置相应的权限 <uses-permission android:name="android.permission.INTERNET ...

  7. Android中通信协议

    一.TCP/IP协议(传输层协议) 1.Socket与ServerSocket Socket是应用层与TCP/IP协议簇通讯的中间抽象层,Socket是一组接口,在设计模式中,Socket的设计就是门 ...

  8. Android中脱离WebView使用WebSocket实现群聊和推送功能

    WebSocket是Web2.0时代的新产物,用于弥补HTTP协议的某些不足,不过他们之间真实的关系是兄弟关系,都是对socket的进一步封装,其目前最直观的表现就是服务器推送和聊天功能.更多知识参考 ...

  9. Android进程间通信之socket通信

    用Java中的socket编程. 通过socket实现两个应用之间的通信,可以接收和发送数据,同时将接收到的数据显示在activity界面上. Server端: ServerLastly.java p ...

随机推荐

  1. 走进JavaScript——重拾函数

    创建函数 通过构造器的方式来创建函数,最后一个参数为函数体其他为形参 new Function('a','b','alert(a)') /* function anonymous(a,b) { ale ...

  2. open-falcon-agent插件使用

    说明 Plugin可以看做是对agent功能的扩充.使用插件可以对采集脚本进行统一管理,方便定制修改,也可以免去在crontab中添加计划任务. 开启plugin功能 # 修改agent配置文件 &q ...

  3. 【翻译】我如何使用CSS来制作bitsofcode Logo动画

    翻译文章,翻译不好,还望大家指出 原文地址:How I Animated the bitsofcode Logo with CSS 我是css动画的新手,这样说是因为我只在有限的案例中使用过他们,而且 ...

  4. 微信小程序内嵌网页 网站生成小程序

    1. 进入小程序后台 - 设置 - 开发设置 2. 添加业务域名(小程序只支持https) 3. 小程序代码 <web-view src="网址"></web-v ...

  5. mybatis3:Invalid bound statement (not found)

    最近在玩ssm框架搭建,突然发现最后的时候mybaits和SpringMvc进行整合的时候出现错误 Invalid bound statement (not found) 这个错误有可能出现在以下几个 ...

  6. PHP函数register_shutdown_function的用法

    register_shutdown_function这个函数是在PHP程序运行结束之前调用的,用这个函数可以做很多,比如调用运行发生致命错误中止的原因,或者调试程序的执行时间等. PHP终止的情况有哪 ...

  7. 微信小程序半周问题总结

    新产品要做一个微信小程序,不想吐槽老板没给任何准备就给出了需求和原型图,好像默认小程序闭着眼睛就可以很顺利开发好.现在半周下来(五一结束开始到今天)完成了差不多所有的界面,网络请求部分还跟服务端兄弟耗 ...

  8. SpringBoot Hello World

    本文首发于我的github博客 前言 SpringBoot是Spring MVC升级版,基于『约定优于配置』的原则,快速开发出web程序. 环境 本系列笔记环境如下: Sun JDK1.8.0_20 ...

  9. CodeForces - 788B Weird journey 欧拉路

    题意:给定n个点,m条边,问能否找到多少条符合条件的路径.需要满足的条件:1.经过m-2条边两次,剩下两条边1次  2.任何两条路的终点和起点不能相同. 欧拉路的条件:存在两个或者0个奇度顶点. 思路 ...

  10. HDU - 1847 巴什博弈

    思路:    0  1  2  3  4  5  6  7  8  9 10 11 12    P N  N P  N N  P N N  P N   N   P 不难发现:当n为三的倍数时,KIKI ...