iOS端Socket连接、发送数据

原文链接

一、Socket的应用
IM即时通讯是通过Socket的方式实现长连接,可运用于 
(1)直播聊天室、礼物 
(2)微信、QQ等即时聊天 
(3)游戏对话、技能等

二、SOCKET原理
套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行。建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket,另一个运行于服务器端,称为ServerSocket。建立连接时所需的寻址信息为IP地址和端口号

IP地址:用于区分那一台机器需要建立连接 
端口号:用于区分和哪一个应用程序建立连接

套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。

三、iOS端使用的Socket
简单的来说,Socket是我们使用TCP/IP 或者UDP/IP协议的一组编程接口,其介于应用层和传输层之间。传输层可以选择TCP或UDP,UDP是不可靠传输,为了保证数据的可靠性,实现起来会更加复杂,所以一般项目使用TCP即可。iOS使用Socket的常用方式有如下: 
(1)BSD Socket:是UNIX系统中通用的网络接口,基于C语言,比较底层 
(2)CF Socket:苹果官方提供,来自于CoreFoundation框架 
(3)AsyncSocket:对BSD Socket的封装,OC语言 
(4)ysocket:对BSD Socket的封装,Swift语言 
在下面的Swift例子中,会使用ysocket

四、客户端(iOS程序)
(1)新建项目client 
(2)将ysocket添加到项目中 
 
(3)新建HYSocket管理类,提供socket连接、发送消息、断开连接等 
(4)在HYSocket中实现init(addr : String, port : Int)初始化方法,通过地址和端口号来初始化TCPClient

class HYSocket {
    fileprivate var tcpClient : TCPClient

    init(addr : String, port : Int) {
        tcpClient = TCPClient(addr:addr, port:port)
    }
}
1
2
3
4
5
6
7
(5)实现connectServer()方法,实现连接Socket服务器

extension HYSocket {
    func connectServer() -> Bool {
        let temp = tcpClient.connect(timeout: 5)
        print(temp.1)
        return temp.0
    }
}
1
2
3
4
5
6
7
(6)在主函数中,初始化HYSocket类,并调用connectServer()进行连接

class ViewController: UIViewController {

    fileprivate lazy var socket : HYSocket = HYSocket(addr: "0.0.0.0", port: 7878)

    override func viewDidLoad() {
        super.viewDidLoad()
        if socket.connectServer() {
            print("连接上服务器")
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
五、服务器端(Mac OS程序)
代码:https://github.com/dolacmeng/socketConnectDemo/tree/connect/ServerDemo

六、测试连接
(1)运行服务器端(Mac程序),点击开启 
 
(2)运行客户端(iOS程序),服务器和客户端Socket连接成功后,打印出连接成功: 


连接的完整代码:https://github.com/dolacmeng/socketConnectDemo/tree/connect

七、发送消息
TCP在传输数据时,传输的是字节流,因此在读取消息时,需要知道数据的长度,否则会出现读取不完整或读取过多的情况。可以通过【长度数据+真实数据】的方式传输数据

1.在HYSocket类中,添加发送消息的方法

extension HYSocket {

    //...

    func sendMsg(data : Data){
        tcpClient.send(data: data)
    }
}
1
2
3
4
5
6
7
8
2.在HYSocket类中,继续添加发送文字消息方法

func sendMsg(message: String) {
    //1.获取消息长度
    let data = message.data(using: .utf8)!
    print(data.count)
    var length = data.count

    //将消息长度写入data
    let headerData = Data(bytes:&length, count: 4)

    //发送消息
    let totalData = headerData + data
    socket.sendMsg(data: totalData)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
3、简单布局界面,并在相应的点击方法中,调用HYSocket对应方法: 


class ViewController: UIViewController {

    fileprivate lazy var socket : HYSocket = HYSocket(addr: "0.0.0.0", port: 7878)

    @IBOutlet weak var contentTextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()


    }

    //点击发送
    @IBAction func clickSend(_ sender: UIButton) {
        guard let content = contentTextField.text else{
            return
        }

        socket.sendMsg(message: content);
    }

    //点击连接
    @IBAction func clickConnect(_ sender: UIButton) {
        if socket.connectServer() {
            print("连接上服务器")
            socket.sendMsg(message: "您好啊,服务器");
        }
    }


    @IBAction func clickDisconnect(_ sender: UIButton) {
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
服务器端读取数据核心代码:

//获取数据长度的data
let lMsgData = Data(bytes: lMsg, count: 4)  
var length : Int = 0
(lMsgData as NSData).getBytes(&length, length: 4)

//根据长度读取消息
guard let msg = tcpClient.read(length) else{
    return
}
let msgData  = Data(bytes: msg, count: length)
let msgString = String(data: msgData, encoding: .utf8)
print(msgString!)
1
2
3
4
5
6
7
8
9
10
11
12
4.测试:客户端点击连接,然后输入要发送的文字,点击发送: 


八、心跳包
心跳包就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时间间隔发送,类似于心跳,所以叫做心跳包。 
在本例中,在Socket连接成功后,开启一个定时服务,每隔9秒发送一次消息给服务器,跟服务器约定好心跳包的内容,将上文中的clickConnect函数修改为:

    //点击连接
    @IBAction func clickConnect(_ sender: UIButton) {
        if socket.connectServer() {
            print("连接上服务器")
            socket.startReadMsg()
            socket.sendMsg(message: "您好啊,服务器");

            //定时发送心跳包
            timer = Timer(fireAt: Date(), interval: 8, target: self, selector: #selector(sendHeartBeat), userInfo: nil, repeats: true)
            RunLoop.main.add(timer, forMode: .commonModes)
        }

    }
1
2
3
4
5
6
7
8
9
10
11
12
13
实现上面代码的sendHeartBeat方法

extension ViewController{
    @objc fileprivate func sendHeartBeat(){
    socket.sendHeartBeat()
    }
}
1
2
3
4
5
在HYSocket中,实现发送心跳包的方法

func sendHeartBeat() {
        //心跳包数据
        let heartString = "i am a heart beat"        
        //发送心跳包数据
        sendMsg(message: heartString)
    }
1
2
3
4
5
6
   
用来判断对方(设备,进程或其它网元)是否正常运行

下一篇:通过ProtocolBuffer来封住啊消息内容并发送: 
https://blog.csdn.net/dolacmeng/article/details/81136635

本篇完整代码:https://github.com/dolacmeng/socketConnectDemo/tree/sendMsg
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值