利用codeblocks实现socket_Android 基于 TCP 的 Socket 编程实现

本文介绍了如何利用Codeblocks进行TCP Socket编程,包括Socket、DatagramSocket、ServerSocket和相关类的使用方法。通过示例展示了TCP通信的服务端和客户端实现,帮助读者深入理解Socket通信过程。

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

两个进程进行通讯最基本的前提是能唯一标识一个进程,在本地进程通讯中可以使用 PID 来唯一标识一个进程,但 PID 在本地是唯一的,网络中两个进程 PID 冲突几率很大,这就要通过其他手段来唯一标识进程了,IP 层的 ip 地址可以唯一标示主机,再结合 TCP 端口号就可以唯一标示某个主机的进程。

唯一标示网络中的进程后,就可以利用 Socket 通信了,到底什么是 Socket 呢?我们经常把 Socket 翻译为套接字,Socket 是在应用层和传输层之间的一个抽象层,它把 TCP/IP 层复杂的操作抽象为几个简单的接口供应用层调用,从而实现进程在网络中通信。

ee90060fa72dd362e7a3ce2afaee6890.png

Socket 编程,可以基于 TCP 或 UDP 实现,Java 为 Socket 编程封装了几个重要的类,我们来认识一下:

Socket (TCP)

Socket 类实现了一个客户端 Socket,作为两台机器通信的终端,默认采用的传输层协议为可靠的 TCP 传输协议,主要方法如下:

  • connect() 用于请求一个 socket 连接
  • getOutputStream 用于获得写 socket 的输出流
  • getInputStream 用于获得读 socket 的输入流
  • close 用于关闭一个流。
DatagramSocket (UDP)

DatagramSocket 类实现了一个发送和接收数据报的 socket,传输层协议使用 UDP,不能保证数据报的可靠传输,主要方法如下:

  • send 用于发送一个数据报,Java 提供了 DatagramPacket 对象用来表达一个数据报
  • receive 用于接收一个数据报,调用该方法后,一直阻塞接收到直到数据报或者超时
  • close 关闭一个 socket。
ServerSocket

ServerSocket 类实现了一个服务端 socket,服务端 socket 等待客户端网络请求,然后基于这些请求执行操作,并返回给请求者结果,主要方法如下:

  • bind 方法为 ServerSocket 绑定一个 IP 地址和端口,并开始监听该端口
  • accept 方法为 ServerSocket 接受请求并返回一个 Socket 对象,accept 方法调用后,将一直阻塞直到有请求到达
  • close 方法关闭一个 ServerSocket 对象。
SocketAddress

SocketAddress 提供了一个 socket 地址,不关心传输层协议。这是一个虚类,由子类来具体实现功能、绑定传输协议。它提供了一个不可变的对象,被 socket 用来绑定、连接或者返回数值。

InetSocketAddress

InetSocketAddress 实现了 IP 地址的 SocketAddress,也就是有 IP 地址和端口号表达 Socket 地址。如果不制定具体的 IP 地址和端口号,那么 IP 地址默认为本机地址,端口号随机选择一个。

DatagramPacket(UDP)

DatagramPacket 表示一个数据包,需要与 DatagramSocket 配合使用才能完成基于数据报的 socket 通信。

代码示例

来看一个简单的 TCP 通信示例,加深对 Socket 编程的了解。

服务端

服务端通过 ServerSocket 实现一个 socket,等待客户端请求:

server = new ServerSocket(PORT);
mExecutorService = Executors.newCachedThreadPool();
while (true) {
  Socket client = server.accept();
  mExecutorService.execute(new Service(client));
}

当 accept 到请求后,启动了一个子线程去处理,处理前先要初始化 IO 流:

public Service(Socket socket) {
  this.socket = socket;
  printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8")), true);
  in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
  printWriter.println("成功连接服务器");//服务端 -> 客户端
}

在任务中接收处理客户端发来的信息,我们假定 “0” 表示客户端主动请求断开:

 while (true) {
  if ((receiveMsg = in.readLine())!=null) {
    System.out.println("receiveMsg:"+receiveMsg);
    if (receiveMsg.equals("0")) {
      System.out.println("客户端请求断开连接");
      printWriter.println("服务端断开连接"); //服务端 -> 客户端
      in.close();
      socket.close();
      break;
    } else {
      sendMsg = "我已接收:" + receiveMsg + "(服务器发送)";
      printWriter.println(sendMsg); //服务端 -> 客户端
    }
  }
 }
客户端

客户端知道服务端 IP 地址及端口号后,通过 Socket 请求建立连接:

Socket socket = new Socket(HOST, PORT);
socket.setSoTimeout(60000);
printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8")), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));

发送和接收数据跟服务端一样,分别通过 PrintWriter 和 BufferedReader 来实现。至此,客户端和服务端就能愉快的进行全双工通信了。

最后附一张图来总结:

3a53e43a89368a70d28f990e28e43fdf.png

推荐阅读:

Zygote 的工作原理

Zygote 的启动流程

Android APT 开发实践

备忘录模式

MemoryFile 共享内存原理分析

Android 匿名共享内存 Ashmem 驱动浅析

迭代器模式

访问者模式

Android 底层的进程间同步机制

8d560ac26d048700378b2e42420c44c2.png

关注我

助你升职加薪

Android 面试官

d47a166b64067a086bed5f0ed930ea01.png fbca8fc259253772ef243e05daf9ec64.png 点赞在看,年薪百万
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值