android byte转string_Android网络编程-Socket

Socket在Android网络编程中,有着非常重要的作用。

Socket基本概念

即套接字,是应用层 与 TCP/IP 协议族通信的中间软件抽象层,表现为一个封装了 TCP / IP协议族 的编程接口(API)。
从设计模式的角度看来,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
借用下网上结构图:

d6b7d6f5486ef73878156bc4f29c4513.png

Socket


IP地址和端口号组成了Socket,都是成对出现。

Socket ={(IP地址1:PORT端口号),(IP地址2:PORT端口号)}

单独的Socke是没用任何作用的,基于一定的协议(TCP或者UDP)下的Socket编程才能进行数据传输。

Socket工作流程

2667fb068e2e34b8a0504b418dac1bf7.png

Socket工作流程


服务端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。
客户端初始化一个socket,然后连接服务器(connect),如果连接成功,这时客户端与服务端的连接就建立了。
客户端发送数据请求,服务端接收请求并处理请求,然后把回应数据发给客户端,客户端读取数据,最后关闭数据,一次交互结束。

分类

Socket使用类型有两种:

  • 基于TCP协议,流套接字,采用流的方式提供可靠的字节流服务
  • 基于UDP协议,数据报套接字,采用数据报文提供数据打包发送的服务

基于TCP的Socket编程

主要API

Socket

构造方法
public Socket(String host, int port)        throws UnknownHostException, IOException

创建流套接字并将其连接到指定主机上的指定端口号。

  • host: 主机地址
  • port: 端口号
getInputStream

返回Socket的输入流,用户接受数据。

getOutputStream

返回Socket的输出流,用于发送数据。

ServerSocket

Socket的服务端实现

构造函数
public ServerSocket(int port) throws IOException

创建服务端Socket,绑定到指定端口。

  • port: 端口号
accept
public Socket accept() throws IOException

监听并接受到此套接字的连接。该方法将阻塞,直到建立连接。

示例

服务端

public class Server {    public static void main(String[] args) throws IOException {        //1. 创建ServerSocket        ServerSocket serverSocket = new ServerSocket(8888);        //2. 监听        Socket socket = serverSocket.accept();        System.out.println("server start listen");        //3. 输入流        InputStream is = socket.getInputStream();        InputStreamReader reader = new InputStreamReader(is);        BufferedReader br = new BufferedReader(reader);        String content = null;        StringBuffer sb = new StringBuffer();        while ((content = br.readLine()) != null) {            sb.append(content);        }        System.out.println("server receiver: " + sb.toString());        socket.shutdownInput();        br.close();        reader.close();        is.close();        socket.close();        serverSocket.close();    }}

非常简单的Socket服务端,接收到客户端的数据,就会关闭当前的连接。这个示例只是展示了一个完整的流程。
如果需要复杂的服务端实现,可以使用Netty、Mina或者其他Socket框架。

客户端

//1. 创建客户端Socket socket = new Socket("your ip", 8888);//2. 输出流OutputStream os = socket.getOutputStream();//3. 发送数据os.write("Hello world".getBytes());System.out.println("send message");os.flush();socket.shutdownOutput();os.close();socket.close();

客户端就是连接后,发送了一份数据,就关闭连接了。
这样就实现了客户端和服务端的通信。

基于UDP的Socket编程

主要API

DatagramPacket

用来包装接收和发送的数据。

  • 构造接收数据包
public DatagramPacket(byte[] buf,int length)

用来接收长度为 length 的数据包。

  • 构造发送数据包
DatagramPacket(byte[] buf, int length,SocketAddress address)DatagramPacket(byte[] buf, int length, InetAddress address, int port)

用来将长度为 length 的包发送到指定主机上的指定端口号。

DatagramSocket

用来发送和接收数据报包的套接字。

构造方法
//创建数据报套接字并将其绑定到本地主机上的指定端口DatagramSocket(int port)  //创建数据报套接字,将其绑定到指定的本地地址DatagramSocket(int port, InetAddress laddr)
发送数据
void send(DatagramPacket p)

DatagramPacket 包含的信息指示:将要发送的数据、其长度、远程主机的 IP 地址和远程主机的端口号

接收数据
void receive(DatagramPacket p)

当此方法返回时,DatagramPacket的缓冲区填充了接收的数据。

示例

服务端

public class UDPServer {    public static void main(String[] args) throws IOException {        byte[] buf = new byte[1024];        // receive        // 1.create        DatagramPacket packet = new DatagramPacket(buf, buf.length);        // 2.create udp socket        DatagramSocket socket = new DatagramSocket(8888);        // 3. receive start        socket.receive(packet);        // 4. receive data        System.out.println("sever: " + new String(buf, 0, buf.length));        // send        DatagramPacket p = new DatagramPacket(buf, buf.length,                         packet.getAddress(), packet.getPort());        socket.send(p);        socket.close();    }}

客户端

// sendInetAddress address = InetAddress.getByName("your ip");//1.create packetDatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, 8888);//2.create socketDatagramSocket socket = new DatagramSocket();//3.send datasocket.send(packet);// receive//1.create packetfinal byte[] bytes = new byte[1024];DatagramPacket receiverPacket = new DatagramPacket(bytes, bytes.length);socket.receive(receiverPacket);System.out.println("client: " + new String(bytes, 0, bytes.length));socket.close();

客户端和服务端的实现,都比较简单。

关于Socket编程,就介绍好了,这篇只是开了头,最主要的还是得去项目中实践。

参考

  • Android:这是一份很详细的Socket使用攻略
  • Scoket编程
网络编程Android开发中非常重要的一部分,主要涉及到Socket通信、HTTP网络请求和Websocket等。下面是一个简单的Android网络编程实验: 实验目的:通过使用Socket通信实现Android客户端与服务器的通信。 实验步骤: 1.创建一个Android工程,并在MainActivity中布局一个EditText和一个Button。 2.在MainActivity中添加以下代码: ```java private EditText etContent; private Button btnSend; private Socket socket = null; private OutputStream outputStream = null; private InputStream inputStream = null; private String ip = "192.168.1.100";//服务器的IP地址 private int port = 8888;//服务器的端口 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etContent = findViewById(R.id.et_content); btnSend = findViewById(R.id.btn_send); btnSend.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final String content = etContent.getText().toString(); new Thread(new Runnable() { @Override public void run() { try { if (socket == null) { socket = new Socket(ip, port); outputStream = socket.getOutputStream(); inputStream = socket.getInputStream(); } outputStream.write(content.getBytes()); outputStream.flush(); byte[] buffer = new byte[1024]; int len = inputStream.read(buffer); String result = new String(buffer, 0, len); Log.d("MainActivity", "result:" + result); } catch (IOException e) { e.printStackTrace(); } } }).start(); } }); } @Override protected void onDestroy() { super.onDestroy(); try { if (socket != null) { socket.close(); } if (outputStream != null) { outputStream.close(); } if (inputStream != null) { inputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } ``` 3.运行程序,在EditText中输入内容,点击Button发送数据,程序会将数据通过Socket通信发送到服务器,并接收服务器返回的数据。 注意事项: 1.需要在AndroidManifest.xml文件中添加网络权限: ```xml <uses-permission android:name="android.permission.INTERNET" /> ``` 2.由于网络通信是耗时操作,所以需要在子线程中进行。 3.需要在程序退出时关闭Socket、输入流和输出流,以免造成资源浪费。 4.需要保证手机和服务器在同一局域网内,才能正常通信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值