Socket通讯

本文介绍如何使用GCDAsyncSocket框架进行Socket通讯,并提供了一个基于系统自带库实现的Socket通讯示例,包括创建、连接及数据收发等关键步骤。
Socket通讯
< GCDAsyncSocket >框架
1. 创建
@property (nonatomic, strong) GCDAsyncSocket *socket; // socket
@property (nonatomic, copy ) NSString *socketHost; // socket的Host
@property (nonatomic, assign) UInt16 socketPort; // socket的prot

    self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
2. 连接
    self.socketHost = self.ip.text;
    self.socketPort = [self.port.text intValue];

    [self.socket connectToHost:self.socketHost onPort:self.socketPort error:nil];

    // 断开连接
    [self.socket disconnect];
3. GCDAsyncSocketDelegate
// 发送数据回调
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
    NSLog(@"didWriteDataWithTag");
}
// 读取数据回调
- (void)socket:(GCDAsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag {
    NSLog(@"didReadData");
}
// 连接失败回调
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err {
    NSLog(@"socketDidDisconnect");
}
// 连接成功回调
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
    NSLog(@"didConnectToHost")
}
系统自带
#import "ViewController.h"
// 导入下面三个头文件
#import <sys/socket.h>
#import <arpa/inet.h>
#import <netinet/in.h>

@interface ViewController ()
/**
 *  IP 地址
 */
@property (weak, nonatomic) IBOutlet UITextField *ipField;
/**
 *  端口号
 */
@property (weak, nonatomic) IBOutlet UITextField *portField;
/**
 *  输入框
 */
@property (weak, nonatomic) IBOutlet UITextField *inputField;
/**
 *  显示服务器返回的结果文本标签
 */
@property (weak, nonatomic) IBOutlet UILabel *recvLabel;
/**
 *  客户端socket
 */
@property(nonatomic,assign) int  clientSocket;

@end

@implementation ViewController
/**
 *  监听连接按钮
 */
- (IBAction)connect {
    BOOL result = [self connectToHost:self.ipField.text port:self.portField.text.intValue];
    if (result) {
        NSLog(@"成功");
    } else {
        NSLog(@"失败");
    }
    self.recvLabel.text = result ? @"成功":@"失败";
}
/**
 *  监听发送按钮
 */
- (IBAction)send {
    // 获得用户输入的内容
    NSString *msg = self.inputField.text;
    // 发送并接收服务响应
    NSString *resultStr = [self sendAndRevc:msg];
    self.recvLabel.text = resultStr;
}

/**
 *  发送数据和接收数据
 */
- (NSString *)sendAndRevc:(NSString *)msg{
    /*
     void * 等价 id
     参数1:客户端的socket
     参数2: 要发送的内容
     参数3: 要发送内容的长度,字节
     发送标示位 传0即可
     */
    //    NSLog(@"%zd--字节长度= %ld",msg.length,strlen(msg.UTF8String));
    // 发消息
    ssize_t sendLength = send(self.clientSocket, msg.UTF8String, strlen(msg.UTF8String), 0);
    NSLog(@"sendLength = %ld",sendLength);
    // 接收服务器返回的数据
    /*
     参数1:客户端的socket
     参数2: 要接收内容才数组
     参数3: 要接收内容的长度,字节
     参数4:传0,标示阻塞式,等待服务器的响应
     */
    // 缓冲区,不能使用字符指针
    uint8_t buffer[1024];
    //    NSLog(@"ffff = %d",sizeof(buffer));
    ssize_t recvLength = recv(self.clientSocket, buffer, sizeof(buffer), 0);
    NSLog(@"recvLength = %ld",recvLength);
    // 获得服务器返回的二进制数据
    NSData *data = [NSData dataWithBytes:buffer length:recvLength];
    // 转换成字符串
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

/**
 *  连接
 */
- (BOOL)connectToHost:(NSString *)host port:(int)port{
    /**
     参数
     domain:    协议域/协议族,AF_INET(IPV4的网络开发)
     type:      Socket 类型,SOCK_STREAM(TCP)/SOCK_DGRAM(UDP,报文)
     protocol:  IPPROTO_TCP,协议,如果输入0,可以根据第二个参数自动选择协议

     返回值
     socket,如果>0 就表示成功
     */
    // 创建socket
    self.clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    // 连接到服务器
    struct sockaddr_in serverAddress;
    // ip 根据ip找主机
    serverAddress.sin_addr.s_addr = inet_addr(host.UTF8String);
    // 端口 根据端口号找程序
    serverAddress.sin_port = htons(port);
    // 协议 确定数据的传输格式
    serverAddress.sin_family = AF_INET;
    // 传递结构体的长度
    // 成功返回0,失败返回 错误代码
    // 在c语言中,一般传递结构体地址的函数,还需要传递结构体的长度
     return (connect(self.clientSocket, (const struct sockaddr *)&serverAddress, sizeof(serverAddress)) == 0);
}

仅供参考,错误勿怪!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值