Android的文本型pKn是什么,Android 中的Socket通讯机制

本文详细介绍了Android中使用Socket进行网络通信的原理与实践,包括TCP和UDP的区别。TCP提供可靠的数据流服务,确保数据正确传输,而UDP则是简单快速但不可靠的数据报协议。在示例中,展示了如何创建TCP和UDP的客户端,以及如何发送和接收数据。在实际应用中,需要注意模拟器环境下UDP数据包的接收问题,以及AndroidManifest.xml中添加相应的权限。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android中的网络通讯无非Http和Socket,Socket有两种形式——TCP和UDP。

TCP与UDP区别

TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

下面通过一个简单的例子介绍一下两种形式的客户端。

Socket socket = new Socket("192.168.3.119",7628);//创建Socket实例,并绑定连接远端IP地址和端口

OutputStream ops = socket.getOutputStream();//定义一个输出流,来自于Socket输出流

byte[] bytes = b.getBytes();

ops.write(bytes);//向输出流中写入数据

ops.flush();//刷行输出流

//至此,在连接成功的情况下,服务端应该就能收到发送过去的流了。

//接下来是接收服务器发送过来的数据

InputStream ips = socket.getInputStream();//定义输入流,来自于socket的输入流

byte[] bytes2 = new byte[20];

ips.read(bytes2);//读取输入流数据

String str = new String(bytes2);//转换成字符串

btn.setText(str);//显示出来(我是现实在button上,当然,这个方法不正规,不过可以让我少放点空间,看上去界面干净点,只要能看到效果就行)

socket.close();

接下来是UDP的

DatagramSocket dgs = new DatagramSocket();//建立一个Socket,这个Socket将作为一个发送器,将Socket包发送出去

InetAddress inet = InetAddress.getByName("192.168.3.119");//创建一个InetAddress,ip地址为要发动到的远端的服务器IP

DatagramPacket dgp = new DatagramPacket("test2".getBytes(), "test2".getBytes().length,inet,7628);//创建一个UDP数据包,数据包包含远端的IP地址及端口

dgs.send(dgp);//发送

dgs.close();

DatagramSocket dgs2 = new DatagramSocket(9997);//创建另一个UDPSocket,

DatagramPacket dgp2 = new DatagramPacket(new byte[20],20); //创建一个空报文包

dgs2.receive(dgp2);//接收数据并填充到报文包中

String str = new String(dgp2.getData());//获取报文包里的数据并转换成字符串

btn.setText(str);//显示获得的数据

dgs2.close();//关闭Socket

需要特别注意的地方,在不做端口映射的情况下,UDP可能无法接受到服务器端发送过来的数据,原因是使用eclipse开发的时候,调试程序是用的模拟环境,模拟环境下,接收数据是要做端口映射的,因为模拟环境下,没有自己真实的IP地址和端口,模拟器是使用5554来运行的,发送数据到PC没问题,但是 PC发送到模拟器的时候,需要把本机的端口映射到模拟器上,真机环境不需要,具体操作方式如下

1、运行模拟器

2、打开DOS命令行窗口

执行:telnet localhost 5554

5554是模拟器的端口,执行之后会进入android console

3、 在console下执行:

redir add udp :8000:9000

其中,第一个端口号是PC的端口,第二个端口号是模拟器端口。

执行此命令之后,会把PC 8000端口接收到的数据转到模拟器的9000端口,模拟器就能从9000端口接收UDP数据包了

另外,要实现Socket,必须在 AndroidManifest.xml 中加入权限如下

1

服务器端:

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

public class SocketActivity extends Activity {

/** Called when the activity is first created. */

private Button startButton = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

startButton = (Button)findViewById(R.id.startListener);

startButton.setOnClickListener(new StartSocketListener());

}

class StartSocketListener implements OnClickListener{

@Override

public void onClick(View v) {

new ServerThread().start();

}

}

class ServerThread extends Thread{

/*public void run(){

//声明一个ServerSocket对象

ServerSocket serverSocket = null;

try {

//创建一个ServerSocket对象,并让这个Socket在7628端口监听

serverSocket = new ServerSocket(7628);

//调用ServerSocket的accept()方法,接受客户端所发送的请求

Socket socket = serverSocket.accept();

//从Socket当中得到InputStream对象

InputStream inputStream = socket.getInputStream();

byte buffer [] = new byte[1024*4];

int temp = 0;

//从InputStream当中读取客户端所发送的数据

while((temp = inputStream.read(buffer)) != -1){

System.out.println(new String(buffer,0,temp));

}

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

finally{

try {

serverSocket.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}*/

public void run(){

try {

//创建一个DatagramSocket对象,并指定监听的端口号

DatagramSocket socket = new DatagramSocket(7628);

byte data [] = new byte[1024];

//创建一个空的DatagramPacket对象

DatagramPacket packet = new DatagramPacket(data,data.length);

//使用receive方法接收客户端所发送的数据

socket.receive(packet);

String result = new String(packet.getData(),packet.getOffset(),packet.getLength());

System.out.println("result--->" + result);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值