iOS Socket 简单使用

162 阅读1分钟

参考 iOS 用原生代码写一个简单的socket连接 自己实现了下 Socket,代码记录如下

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

//htons : 将一个无符号短整型的主机数值转换为网络字节顺序,不同cpu 是不同的顺序 (big-endian大尾顺序 , little-endian小尾顺序)
#define SocketPort htons(8040) //端口
//inet_addr是一个计算机函数,功能是将一个点分十进制的IP转换成一个长整数型数
#define SocketIP inet_addr("127.0.0.1") // ip

@interface ViewController ()
@property (nonatomic, assign) int clinenId;

@property (nonatomic, strong) UIButton *connectBtn;
@property (nonatomic, strong) UITextView *recvMsgView;

@property (nonatomic, strong) UITextField *textField;
@property (nonatomic, strong) UIButton *sendBtn;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _connectBtn = [[UIButton alloc] initWithFrame:CGRectMake(100, 60, 200, 40)];
    _connectBtn.backgroundColor = [UIColor grayColor];
    [_connectBtn setTitle:@"connect" forState:UIControlStateNormal];
    [_connectBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    [_connectBtn addTarget:self action:@selector(connectBtnClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_connectBtn];
    
    _textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 140, 150, 20)];
    _textField.layer.borderColor = [UIColor grayColor].CGColor;
    _textField.layer.borderWidth = 0.5;
    [self.view addSubview:_textField];
    
    _sendBtn = [[UIButton alloc] initWithFrame:CGRectMake(260, 140, 40, 20)];
    _sendBtn.backgroundColor = [UIColor grayColor];
    [_sendBtn setTitle:@"send" forState:UIControlStateNormal];
    [_sendBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    [_sendBtn addTarget:self action:@selector(sendBtnClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_sendBtn];
    
    _recvMsgView = [[UITextView alloc] initWithFrame:CGRectMake(100, 200, 200, 200)];
    _recvMsgView.text = @"msg:";
    _recvMsgView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:_recvMsgView];
}

- (void)connectBtnClick {
    //创建
    int socketID = socket(AF_INET, SOCK_STREAM, 0);
    self.clinenId = socketID;
    if (socketID == -1) {
        NSLog(@"创建失败");
        return;
    }
    
    //连接
    struct sockaddr_in socketAddr;
    socketAddr.sin_family = AF_INET;
    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(@"连接失败");
    }
    NSLog(@"连接成功");
    
    //调用开始接受信息的方法
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self recvMsg];
    });
    
}

- (void)sendBtnClick {
    //发送消息
    if (self.textField.text.length == 0) {
        return;
    }
    
    const char *msg = self.textField.text.UTF8String;
    ssize_t sendLen = send(self.clinenId, msg, strlen(msg), 0);
    NSLog(@"发送 %ld 字节", sendLen);
}

- (void)recvMsg {
    //接收数据
    while (1) {
        uint8_t buffer[1024];
        ssize_t recvLen = recv(self.clinenId, buffer, sizeof(buffer), 0);
        NSLog(@"接收到了:%ld字节",recvLen);
        if (recvLen == 0) {
            continue;
        }
        
        NSData *data = [NSData dataWithBytes:buffer length:recvLen];
        NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%@---%@",[NSThread currentThread],str);
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            self.recvMsgView.text = [NSString stringWithFormat:@"%@\n%@",self.recvMsgView.text,str];
        });
    }
}
@end