美文网首页
基于socket的“抽奖”

基于socket的“抽奖”

作者: 携一两本单色书来 | 来源:发表于2016-12-20 10:28 被阅读33次

    socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。

    多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

    建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket,另一个运行于服务器端,称为ServerSocket。套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

    Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接,UDP连接同理。

    原理图

    AsyncUdpSocket:

    这里用到了一个三方AsyncUdpSocket,原来的下载地址不过现在不能用了,github有类似的,应该也可以直接用。这套抽奖是socket的及其简单的应用,写两套代码分别给操作端和现实端。

    抽奖时用的是随机数对20取余,而最后的“现在”就是通过socket发送到现实端的。
    显示端:


    代码很简单,这里我就直接粘了:

    #import "ViewController.h"
    #import "AsyncUdpSocket.h"
    #import <AVFoundation/AVFoundation.h>
    
    #define RandomColor [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0]//随机色
    
    #define screenWidth [UIScreen mainScreen].bounds.size.width
    #define screenHeight [UIScreen mainScreen].bounds.size.height
    
    
    @interface ViewController ()<AsyncUdpSocketDelegate>{
    AsyncUdpSocket *_socket;
    NSTimer *_timer;
    NSString *_lastStr;
    UIButton *startBut;
    
    
    }
    
    @property (nonatomic,strong)AVPlayer *player;
    @property (nonatomic,strong)UILabel *label;
    
    @end
    
    @implementation ViewController
    
    //懒加载播放器
    - (AVPlayer *)player{
    if (_player == nil) {
        // 1.获取URL(远程/本地)
         NSURL *url = [[NSBundle mainBundle] URLForResource:@"M11-01-05-57.mp3" withExtension:nil];
        //NSURL *url = [NSURL URLWithString:@"http://v1.mukewang.com/a45016f4-08d6-4277-abe6-bcfd5244c201/L.mp4"];
        
        // 2.创建AVPlayerItem
        AVPlayerItem *item = [AVPlayerItem playerItemWithURL:url];
        
        // 3.创建AVPlayer
        _player = [AVPlayer playerWithPlayerItem:item];
        
        // 4.添加AVPlayerLayer
        AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:self.player];
        layer.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.width * 9 / 16);
        [self.view.layer addSublayer:layer];
    }
    return _player;}
    
    //搭建页面  
    - (void)viewDidLoad {
    [super viewDidLoad];
    
    _label = [[UILabel alloc] initWithFrame:CGRectMake(screenWidth/2-150, 100, 300, 300)];
    _label.backgroundColor = [UIColor orangeColor];
    _label.font = [UIFont systemFontOfSize:33.0f weight:21];
    _label.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:self.label];
    
    startBut = [[UIButton alloc] initWithFrame:CGRectMake(screenWidth/2-50, screenHeight-200, 100, 50)];
    [startBut setBackgroundColor:[UIColor redColor]];
    [startBut setTitle:@"开始抽奖" forState:UIControlStateNormal];
    [startBut addTarget:self action:@selector(LetUsBegin) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:startBut];
    
    
    
    _socket = [[AsyncUdpSocket alloc]initIPv4];
    _socket.delegate = self;
    //ip 和 端口号//这个重电脑的网络看,必需要一致
    [_socket bindToAddress:@"10.10.5.32" port:9444 error:nil];
    
    //保持连接
    [_socket receiveWithTimeout:-1 tag:0];
    

    }

    //点击了开始抽奖按钮

    - (void)LetUsBegin{
     startBut.hidden = YES;
    [self.player play];
    _timer = [NSTimer scheduledTimerWithTimeInterval:0.4 target:self selector:@selector(ChangeLabelText) userInfo:nil repeats:YES];
    
    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(9* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self stopTimer];
    });
    

    }

    10秒过后停止

    - (void)stopTimer{
    [_timer invalidate];
    _timer = nil;
    if (_lastStr) {
         _label.text  = _lastStr;
    }else{
        _label.text = [NSString stringWithFormat:@"%i",arc4random()%30];
    }
     startBut.hidden = NO;
    _label.backgroundColor = RandomColor;
    _lastStr = nil;
    self.player = nil;
    }
    

    定时器方法,

    - (void)ChangeLabelText{
    _label.text = [NSString stringWithFormat:@"%i",arc4random()%20];
    _label.backgroundColor = RandomColor;
    

    }

    socket代理方法

    -(BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port{
    
    _lastStr =  [[NSString alloc] initWithData:data  encoding:NSUTF8StringEncoding];
    //保持连接
     [_socket receiveWithTimeout:-1 tag:0];
     return YES;
    

    }

    控制端:

    下面放代码:

    #import "ViewController.h"
    #import "AsyncUdpSocket.h"
    #include <ifaddrs.h>
    #include <arpa/inet.h>
    
    @interface ViewController (){
      AsyncUdpSocket *_socket;
    NSString *_ipAddress;
    }
    
    @property (nonatomic,strong)UITextField *tf;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
    [super viewDidLoad];
    
    //输入框
    _tf = [[UITextField alloc] initWithFrame:CGRectMake(20, 100, 200, 50)];
    _tf.backgroundColor = [UIColor grayColor];
    [self.view addSubview:_tf];
    
    //获取ip地址
    _ipAddress = [self deviceIPAdress];
    NSLog(@"%@",_ipAddress);
    
    UIButton *but = [[UIButton alloc] initWithFrame:CGRectMake(200, 200, 80, 30)];
    [but setBackgroundColor:[UIColor redColor]];
    [but setTitle:@"发送" forState:UIControlStateNormal];
    [but addTarget:self action:@selector(sendTheNumber) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:but];
    }
    

    //初始化socket和发送ip

    - (void)sendTheNumber{
    _socket = [[AsyncUdpSocket alloc]initIPv4];
    _socket.delegate = self;
    //ip 和 端口号
    [_socket bindToAddress:_ipAddress port:9444 error:nil];
    
    //[_socket sendData:data toAddress:@"192.168.1.160" withTimeout:-1 tag:0];
    
    NSData* data = [_tf.text dataUsingEncoding:NSUTF8StringEncoding];
    
    [_socket sendData:data toHost:@"10.10.5.38" port:9444 withTimeout:-1 tag:0];
    
    _tf.text = @"";
    //保持连接
    [_socket receiveWithTimeout:-1 tag:0];
    }
    
    - (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port{
        
    return YES;
    

    }

    //wifi下获取手机ip的方法
    
    - (NSString *)deviceIPAdress {
    NSString *address = @"an error occurred when obtaining ip address";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    
    success = getifaddrs(&interfaces);
    
    if (success == 0) { // 0 表示获取成功
        
        temp_addr = interfaces;
        while (temp_addr != NULL) {
            if( temp_addr->ifa_addr->sa_family == AF_INET) {
                // Check if interface is en0 which is the wifi connection on the iPhone
                if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
                    // Get NSString from C String
                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
                }
            }
            
            temp_addr = temp_addr->ifa_next;
        }
    }
    
    freeifaddrs(interfaces);
    
    NSLog(@"手机的IP是:%@", address);
    return address;
    

    }

    相关文章

      网友评论

          本文标题:基于socket的“抽奖”

          本文链接:https://www.haomeiwen.com/subject/gyuxvttx.html