使用Socket进行设备间点对点连接传输数据

本文介绍了如何使用GCDAsyncSocket进行设备间点对点通讯,通过创建SocketHelper单例类,实现了Server和Client的初始化。Server通过UDP广播自己的IP和端口,Client接收并建立TCP连接进行数据传输。文章提供了SocketHelper的头文件和实现文件,并展示了Server和Client的使用方法,包括启动UDP广播和连接到Server的逻辑。
摘要由CSDN通过智能技术生成

前言

最近在做一套点对点传输的软件, 需要用到Socket进行设备间通讯. 去网上查了查, 对Socket分装比较好的就是目前特别火的GCDAsyncSocket这个类了, 这篇文章就GDCAsyncSocket与GCDAsyncUdpSocket进行单例封装, 一台设备通过UDP广播, 对外发送自己的IP地址与端口号, 另一台设备做接收, 接收后连接到IP地址与端口号, 从而进行TCP连接进行数据传输. 说明一下, SocketHelper单例类是Server与Client两用的, 使用时需指定设备类型. 下面先来看一下SocketHelper.

SocketHelper.h
#import <Foundation/Foundation.h>
#import <arpa/inet.h>
#import <ifaddrs.h>
#import "GCDAsyncSocket.h"
#import "GCDAsyncUdpSocket.h"

#define TAG 999 // 用于设备间通信
#define BROADCAST_HOST  @"255.255.255.255"
#define CLIENT_UDP_PORT 7890
#define TCP_PORT        45000
#define kDATACONVERSION @"Dictionary To Data"

typedef enum : NSUInteger {
    Server,
    Client,
} Type;

@interface SocketHelper : NSObject <GCDAsyncSocketDelegate, GCDAsyncUdpSocketDelegate> {
    dispatch_queue_t  _tcpSocketQueue;
    dispatch_queue_t  _udpSocketQueue;
    dispatch_source_t _source;  // 定时起源
}

@property (nonatomic, strong) GCDAsyncSocket    *tcpSocket;    // Server | Client 进行TCP连接使用
@property (nonatomic, strong) GCDAsyncUdpSocket *udpSocket;    // Server 通过广播向 Client 发送 Server 的IP地址

@property (nonatomic, strong, readonly) NSMutableArray    *connectedSocekts;  // 存放已连接 Socket 的数组
@property (nonatomic, strong, readonly) NSDictionary      *readUdpDataDic;    // @{host:@(port)}
@property (nonatomic, assign) long                tag;                        // 对数据进行区分
@property (nonatomic, assign, readonly) BOOL      isListening;                // Server 开始监听 Client
@property (nonatomic, assign) Type                type;

@property (nonatomic, copy)   NSString *tcpHost;
@property (nonatomic, assign) UInt16    tcpPort;

@property (nonatomic, copy)   NSString *udpHost;
@property (nonatomic, assign) UInt16    udpPort;

#pragma mark - SHARED HELPER
+ (SocketHelper *)sharedHelper;

#pragma mark - BROADCAST
/**
 * 允许 Socket 发送广播
 * @param flag YES or NO
 * @reutrn YES or NO
 */
- (BOOL)enableBroadcast:(BOOL)flag;

#pragma mark - BING
/**
 * 绑定 UDP Socket 的端口
 * @param port 端口号
 * @reutrn YES or NO
 */
- (BOOL)bindToPort:(uint16_t)port;

#pragma mark - RECEIVING
/**
 * 成功开启后可连续接收数据
 * @return YES or NO
 */
- (BOOL)beginReceiving;

/**
 * 成功开启后只接收一次数据, 开在之后添加 - (BOOL)beginingReceiving 做转换
 */
- (BOOL)receiveOnce;

#pragma mark - UDP CONNECT
/**
 * 通过广播对外发送数据
 * @param data 广播的数据
 * @param host 向 host 所在的地址进行广播 @"255.255.255.255"
 * @param port 广播的端口号, 填写 Client 绑定的端口
 */
- (void)broadcastData:(NSData *)data toHost:(NSString *)host port:(uint16_t)port withTag:(long)tag;

/**
 * 开始进行广播
 */
- (void)startedBroadcasting;
/**
 * 开始循环发送广播数据
 */
- (void)startCycle;

#pragma mark - UDP DATA PRPGRESSING
/**
 * 向指定 host:port 发送数据
 * @param data 发送的数据
 * @param host 指定的 IP 地址
 * @param port 指定端口
 * @param tag  通过 tag 的值对传输数据进行分类
 */
- (void)sendData:(NSData *)data toHost:(NSString *)host port:(uint16_t)port withTag:(long)tag;

#pragma mark - TCP CONNECT
/**
 * Server 对指定端口进行监听
 */
- (void)startListeningPort;

/**
 * Client 通过 Host:Port 与 Server 进行连接
 */
- (void)startConnect;

#pragma mark - TCP DATA PRPGRESSING
/**
 * TCP 连接时发送数据
 * @param data 需要传送的数据
 * @param tag  通过 tag 的值对传输数据进行分类
 */
- (void)writeData:(NSData *)data withTag:(long)tag;

#pragma mark - GET IP ADDRESS
/**
 * 获取本机的IP地址
 @return IP地址的字符串
 */
- (NSString *)getIpAddress;

#pragma mark - DATA PRPGRESSING
/**
 * 将
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值