iOS简单的UDP通讯测试

Home / iOS MrLee 2020-4-27 1514

Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。RFC 768 [1]  描述了 UDP。

Internet 的传输层有两个主要协议,互为补充。无连接的是 UDP,它除了给应用程序发送数据包功能并允许它们在所需的层次上架构自己的协议之外,几乎没有做什么特别的事情。面向连接的是 TCP,该协议几乎做了所有的事情。

头文件引用很重要,用错了可能bind失败。。。

#import "ViewController.h"
#import "HttpUtil.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    NSLog(@"App Is Running...");
    // 异步执行任务创建方法
    dispatch_queue_t queue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        // 这里放异步执行任务代码
        [self udpServer];
    });
    // 异步执行任务创建方法
    dispatch_async(queue, ^{
        // 这里放异步执行任务代码
        [self udpClient];
    });
}
- (void)udpClient {
    int clientSocketId;
    ssize_t len;
    socklen_t addrlen;
    struct sockaddr_in client_sockaddr;
    char buffer[256] = "Hello, server, how are you?";
    
    // 第一步:创建Socket
    clientSocketId = socket(AF_INET, SOCK_DGRAM, 0);
    if(clientSocketId < 0) {
        NSLog(@"creat client socket fail\n");
        return;
    }
    
    addrlen = sizeof(struct sockaddr_in);
    bzero(&client_sockaddr, addrlen);
    client_sockaddr.sin_family = AF_INET;
    client_sockaddr.sin_addr.s_addr = inet_addr("192.168.1.101");
    client_sockaddr.sin_port = htons(8877);
    
    int count = 10;
    do {
        bzero(buffer, sizeof(buffer));
        sprintf(buffer, "%s", "Hello, server, how are you?");
        
        // 第二步:发送消息到服务端
        // 注意:UDP是面向无连接的,因此不用调用connect()
        // 将字符串传送给server端
        len = sendto(clientSocketId, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_sockaddr, addrlen);
        
        if (len > 0) {
            NSLog(@"发送成功");
        } else {
            NSLog(@"发送失败");
        }
        
        // 第三步:接收来自服务端返回的消息
        // 接收server端返回的字符串
        bzero(buffer, sizeof(buffer));
        len = recvfrom(clientSocketId, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_sockaddr, &addrlen);
        NSLog(@"receive message from server: %s", buffer);
        
        count--;
    } while (count >= 0);
    
    // 第四步:关闭socket
    // 由于是面向无连接的,消息发出处就可以了,不用管它收不收得到,发完就可以关闭了
    close(clientSocketId);
}
- (void)udpServer {
    int serverSockerId = -1;
    ssize_t len = -1;
    socklen_t addrlen;
    char buff[1024];
    struct sockaddr_in ser_addr;
    
    // 第一步:创建socket
    // 注意,第二个参数是SOCK_DGRAM,因为udp是数据报格式的
    serverSockerId = socket(AF_INET, SOCK_DGRAM, 0);
    
    if(serverSockerId < 0) {
        NSLog(@"Create server socket fail");
        return;
    }
    
    addrlen = sizeof(struct sockaddr_in);
    bzero(&ser_addr, addrlen);
    
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    ser_addr.sin_port = htons(8877);
    
    // 第二步:绑定端口号
    if(bind(serverSockerId, (struct sockaddr *)&ser_addr, addrlen) < 0) {
        NSLog(@"server bind socket fail");
        return;
    }
    
    do {
        bzero(buff, sizeof(buff));
        
        // 第三步:接收客户端的消息
        len = recvfrom(serverSockerId, buff, sizeof(buff), 0, (struct sockaddr *)&ser_addr, &addrlen);
        // 显示client端的网络地址
        NSLog(@"receive from %s\n", inet_ntoa(ser_addr.sin_addr));
        // 显示客户端发来的字符串
        NSLog(@"recevce:%s", buff);
        
        // 第四步:将接收到的客户端发来的消息,发回客户端
        // 将字串返回给client端
        sendto(serverSockerId, buff, len, 0, (struct sockaddr *)&ser_addr, addrlen);
    } while (strcmp(buff, "exit") != 0);
    
    // 第五步:关闭socket
    close(serverSockerId);
}
@end


本文链接:https://www.it72.com/12607.htm

推荐阅读
最新回复 (0)
返回