iOS socket编程(入门)

1.基于 C 的 BSD socket(UNIX系统中通用的网络接口)

感觉BSD socket 最容易理解,最容易入门,最为灵活     但是最难用,尤其对于大型项目

需要导入头文件

#import <sys/socket.h>
#import <netdb.h>

服务器端

    int    listenfd, connfd;
    struct sockaddr_in     servaddr;
    char    buff[4096];
    long     n;
    int i=100;
    
    //创建 socket
    if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
        printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
        return;
    }
    
    //初始化ip地址
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(8088);//要与客户端请求的端口网址一样
    
    //绑定 网址端口
    if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
        printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
        return;
    }
    
    //监听 网址端口
    if( listen(listenfd, 10) == -1){
        printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
        return;
    }
    
    //接受服务器传来的数据
    printf("======waiting for client's request======\n");
    while(i>0){
        if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){
            printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
            continue;
        }
        n = recv(connfd, buff, MAXLINE, 0);
        buff[n] = '\0';
        printf("recv msg from client: %s\n", buff);
        close(connfd);
    }
    
    //关闭socket
    close(listenfd);

客户端

-(void)sendDataToServerURL:(NSURL *)url{
    int    sockfd;
    char    sendline[4096];
    struct sockaddr_in    servaddr;
    NSString * host = [url host];

    
    //创建 socket
    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
        return;
    }
    
    
    //初始化ip地址
    struct hostent * hostEnt = gethostbyname([host UTF8String]);//根据域名 获取ip信息
    if (NULL == hostEnt) {
        NSLog(@"解析域名失败");
        return;
    }
    struct in_addr * remoteInAddr = (struct in_addr *)hostEnt->h_addr_list[0];

    
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(8088);
    servaddr.sin_addr = *remoteInAddr;

    
    //链接TCP服务器(根据ip地址)
    if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
        printf("connect error: %s(errno: %d)\n",strerror(errno),errno);
        return;
    }
    
    //发送字符串到TCP服务器
    printf("send msg to server: \n");
    fgets(sendline, 4096, stdin);
    if(send(sockfd, sendline, strlen(sendline), 0) < 0)
    {
        printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
        return;
    }
    
    //关闭socket
    close(sockfd);
}

2.FCSocket 接口比BSD socket多的多

服务器端和BSD socket有点类似,

客户端的与BSD socket完全不同,使用的是输入输出流。

服务器端

//收到消息监听
static void handleConnect(CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
    NSLog(@"收到信息了");
}
-(void)openFCSocket
{
    //创建 socket
    const CFSocketContext socketCtxt = {0, (__bridge void *)self, NULL, NULL, NULL};
    CFSocketRef  cfSocket = CFSocketCreate(
                                           kCFAllocatorDefault,
                                           PF_INET,
                                           SOCK_STREAM,
                                           IPPROTO_TCP,
                                           kCFSocketAcceptCallBack,
                                           (CFSocketCallBack)handleConnect,//接受信息回调
                                           &socketCtxt);
    
    if (cfSocket == NULL) {
        NSLog(@"创建Socket失败");
        return;
    }
    
    
    //初始化ip地址
    struct sockaddr_in sin;
    memset(&sin, 0, sizeof(sin));
    sin.sin_len = sizeof(sin);
    sin.sin_family = AF_INET; /* Address family */
    sin.sin_port = htons(8088); /* Or a specific port */
    sin.sin_addr.s_addr= INADDR_ANY;
    
    
    //绑定 网址端口
    CFDataRef sincfd = CFDataCreate(
                                    kCFAllocatorDefault,
                                    (UInt8 *)&sin,
                                    sizeof(sin));
    
    if (kCFSocketSuccess != CFSocketSetAddress(cfSocket, sincfd)) {
        NSLog(@"绑定网址端口失败");
    }
    CFRelease(sincfd);
    
    
    //将socket加入  run loop
    CFRunLoopSourceRef socketsource = CFSocketCreateRunLoopSource(
                                                                  kCFAllocatorDefault,
                                                                  cfSocket,
                                                                  0);
    CFRunLoopAddSource(
                       CFRunLoopGetCurrent(),
                       socketsource,
                       kCFRunLoopDefaultMode);

}

客户端

    NSString *host = @"127.0.0.1";
    int port = 8088;

    //创建输入 输出流
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)host,
                                       port, &readStream, &writeStream);
    NSInputStream *inputStream = (__bridge NSInputStream *)readStream;
    NSOutputStream *outputStream = (__bridge NSOutputStream *)writeStream;

    
    if (inputStream == nil || outputStream == nil) {
        NSLog(@"流创建失败!");
        return ;
    }
    
    //启动输入 输出流
    [inputStream open];
    [outputStream open];
    
    
    //发送数据
    NSData *outgoingDataBuffer =  [@"testdata" dataUsingEncoding:NSUTF8StringEncoding];
    NSInteger writtenBytes = [outputStream write:outgoingDataBuffer.bytes maxLength:outgoingDataBuffer.length];
    if ( writtenBytes == -1 ) {
        NSLog(@"发送失败");
        return;
    }
    NSLog(@"发送成功");

3. CocoaAsyncSocket封装了CFSocket

实现了TCP,UDP,加入异步线程,断开重连,TLS/SSL等等,实际开发中需要实现的的东西。

如果没时间重复造轮子,用这类第三方框架也不错



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值