原生代码编写 socket

一、定义

socket,用于双方通信连接以便进行数据交换,连接的双方即为socket。

 

二、客户端

客户端的开发需要用到以下几个方法:

创建socket,socket()

连接socket,connect()

接受消息,recv()

发送消息,send()

1、头文件及宏

#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>

#define SocketPort htons(8081) //端口
#define SocketIP   inet_addr("172.19.203.106") // ip地址
#define SocketFamily AF_INET //协议族

2、socket()

    _socketID = socket(SocketFamily, SOCK_STREAM, 0);
    
    if (_socketID == -1) {
        NSLog(@"创建socket失败");
        return;
        
    }
    else{
        NSLog(@"创建socket成功");
    }

socket() 返回一个 socketID 是 socket 的标识,在传到服务端后用于匹配客户端。

包含三个参数:

1)、协议族,AF_INET - ipv4,AF_INET6 - ipv6等,决定了 socket 的地址类型。

2)、协议类型,SOCK_STREAM - TCP,SOCK_DGRAM - UDP,

3)、协议,一般设为0,会自动与上一个参数对应。

 

3、connect()

    struct sockaddr_in socketAddr;
    socketAddr.sin_family   = SocketFamily;
    socketAddr.sin_port     = SocketPort;
    
    struct in_addr  socketIn_addr;
    socketIn_addr.s_addr    = SocketIP;
    socketAddr.sin_addr     = socketIn_addr;
    
    
    int result = connect(_socketID, (const struct sockaddr *)&socketAddr, sizeof(socketAddr));
    if (result!=0) {
        NSLog(@"连接失败");
        return;
    }
    else{
        NSLog(@"连接成功");
    }

connect() 返回一个 result ,如果为0则说明连接成功,如果不为0则会返回错误码,代表连接失败。

4、recv()

        uint8_t buffer[1024];
        ssize_t recvLen = recv(self.socketID, buffer, sizeof(buffer), 0);
        if (recvLen==0) {
            NSLog(@"接受到的数据为空");
            return;
        }
        // 接收到的数据转换
        NSData *recvData  = [NSData dataWithBytes:buffer length:recvLen];
        NSString *recvStr = [[NSString alloc] initWithData:recvData encoding:NSUTF8StringEncoding];

recv(),需要通过循环加载,用于持续接受消息,否则在接受到第一条消息以后会不再接受其他消息。

recv() 不会一直循环,只有在返回数据以后才能往下执行,所以不用担心会死循环。

当返回的长度为0时,一般代表连接失败,就需要注意连接情况了。

5、send()

    const char *msg = self.textField.text.UTF8String;
    ssize_t sendLen = send(self.socketID, msg, strlen(msg), 0);
    if (sendLen <= 0) {
        NSLog(@"发送失败");
        return;
    }

send(),返回一个发送数据的长度,正常情况下会做发送数据的为空判断,所以如果为0,一般代表发送失败。

6、效果

客户端效果

在填上一些其他控件,即可查看效果。

客户端与服务端连接即可进行通信,这里将通信消息展示在客户端上方便调试。

 

三、服务端

 服务端需要用到以下几个方法:

创建socket:socket();

绑定socket:bind();

监听socket:listen();

接受客户端连接:accept();

接受客户端消息:recv();

发送消息:send();

关闭socket:close();

1、头文件及宏

#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>

#define SocketPort htons(8081)
#define SocketIP   inet_addr("172.19.203.106")
#define SocketFamily AF_INET //协议族
#define kMaxConnectCount 5

2、socket()

同上

3、bind()

        int bind_result = bind(self.serverId, (const struct sockaddr *)&socketAddr, sizeof(socketAddr));
        if (bind_result == -1) {
            NSLog(@"绑定socket 失败");
            return;
        }
        NSLog(@"绑定socket成功");

4、listen()

    int listen_result = listen(self.serverId, kMaxConnectCount);
    if (listen_result == -1) {
        NSLog(@"监听失败");
        return;
    }
    NSLog(@"监听成功");

5、accept()

        struct sockaddr_in client_address;
        socklen_t address_len;
        // accept函数
        int client_socket = accept(self.serverId, (struct sockaddr *)&client_address, &address_len);
        self.client_socket = client_socket;
        
        if (client_socket == -1) {
            NSLog(@"接受 %u 客户端错误",address_len);
        }else{
            NSString *acceptInfo = [NSString stringWithFormat:@"客户端 %d 已连接",client_socket];
            NSLog(@"%@",acceptInfo);
            
            //开始接受消息
            [self receiveMsg];

        }

accept() 接受客户端连接,当连接成功以后,可以添加接受消息方法 recv()。

6、recv()

同上

7、send()

同上

8、close()

    int close_result = close(self.client_socket);
    
    if (close_result == -1) {
        NSLog(@"socket 关闭失败");
        return;
    }else{
        NSLog(@"socket 关闭成功");
    }

关闭以后如果需要重新连接,需要客户端服务端都重新连接才可以。

9、效果

服务端效果

 

服务端与客户端连接以后即可进行通信,这里已经将消息展示在客户端方便调试。

四、其他服务端

1、终端

在终端中输入 nc -lk 8081 ,连接socket即可与客户端进行通信。

效果

 2、YMNetwork

在App Store 下载 YMNetwork

YMNetwork 下载

 

YMNetwork

 

调试很方便。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 跨平台socket封装是指为了在不同操作系统或者硬件平台上运行的应用程序之间进行网络通信,将socket API进行封装,提供统一的接口来使得应用程序可以方便地进行网络通信。由于在不同操作系统或者硬件平台上,socket API的实现方式有所不同,因此需要对不同平台进行适配和封装。跨平台socket封装的目的是方便开发人员进行网络通信,同时提高应用程序的可移植性、兼容性和可扩展性。在跨平台socket封装中,可以使用一些开源的第三方库,比如Boost.Asio、libevent等。这些第三方库提供了一些封装接口,使得应用程序能够使用统一的方式来进行网络编程。 在使用跨平台socket封装时,需要注意以下几点: 1.不同操作系统之间可能存在差异,需要进行相应的适配和兼容性测试。 2.在进行网络通信时,要保证通信协议的一致性,避免数据传输出现丢包或者粘包等问题。 3.要充分理解每个函数的含义和参数,以保证网络编程的正确性和可靠性。 总之,跨平台socket封装为应用程序提供了简单、方便、可移植的网络编程方式,是现代网络通信的重要组成部分。 ### 回答2: 跨平台socket封装是一种将不同操作系统的socket细节进行封装的技术。通过跨平台socket封装,我们可以让不同操作系统的socket代码在不进行修改的情况下在不同的平台上运行。这样可以加快开发者的开发速度,同时降低代码维护难度。 跨平台socket封装技术的实现需要解决两个问题:一是不同操作系统对socket函数的实现细节不同,导致代码实现难度大,需要针对每个操作系统单独编写代码;二是跨平台socket封装技术需要充分考虑移植性问题,需要确保在不同操作系统和硬件平台上稳定运行。 为了解决这些问题,跨平台socket封装技术通常采用C或C++语言编写,使用平台无关的API,例如POSIX API或者Winsock API。同时,跨平台socket封装也需要具备跨平台的编译和构建环境,例如常用的Cmake或者Autotools。 跨平台socket封装的好处是显而易见的,它不仅可以提高开发者的效率,还可以降低代码维护的难度。但是需要注意的是,跨平台socket封装并不是万能的,它需要根据实际应用场景进行选择。如果仅仅是针对特定平台开发应用,使用原生socket API可能更加简单有效。但是在开发跨平台应用或者框架时,使用跨平台socket封装技术是非常重要的。 ### 回答3: 跨平台socket封装是一种将底层的socket通信接口进行封装,使得在不同的操作系统以及开发语言中实现socket通信更加简单和便捷的工具。封装后的跨平台socket可以隐藏底层操作系统的差异性,以统一的接口供用户使用,提高了代码的可复用性和跨平台移植性。 跨平台socket的封装可以通过使用库的方式进行实现,例如常见的Socket.io和Boost.asio库等。这些库提供了高层次的API,使得开发者不再需要关注不同平台和语言下socket通信的实现细节,而是可以直接调用封装好的API进行开发。同时,这些库也提供了众多的工具和函数,能够帮助开发者更加便捷的进行socket通信的开发和调试。 跨平台socket封装的优点不仅在于提高编程效率,还可以提高系统的灵活性和可扩展性。开发者可以更加方便地进行平台切换和升级,同时还可以通过简单的调用来实现多个设备之间的通信。 总之,跨平台socket封装的出现大大方便了软件开发工作,能够满足当今多样化、交互性强的移动互联网市场需求,为开发者提供了高效、可靠的网络通信解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值