socket 通信

送分小仙女□ 提交于 2021-01-04 07:04:23
客户端 
在项目中导入 IPAddress.h, IPAddress.c 这两个类
导入相应的头文件 
#import <UIKit/UIKit.h>
#import <sys/types.h>
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#import <unistd.h>
#import <netdb.h>
#import "IPAddress.h"

实现代码如下
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.navigationController.navigationBar.translucent = NO;

    [self setBtn];
    //[self createConnect];
}
-(void)setBtn
{
    _IPtextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 280, 40)];
    _IPtextField.delegate = self;
    _IPtextField.borderStyle = UITextBorderStyleRoundedRect;
     _IPtextField.placeholder = @"ip地址";
    _IPtextField.text = @"192.168.2.121";
    [self.view addSubview:_IPtextField];
    
    _textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 80, 280, 40)];
    _textField.delegate = self;
    _textField.borderStyle = UITextBorderStyleRoundedRect;
    _textField.placeholder = @"请输入发送消息";
    [self.view addSubview:_textField];
    
    
    _textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 140, 280, 100)];
    _textView.delegate = self;
    _textView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:_textView];
    
    _btn1 = [UIButton buttonWithType:UIButtonTypeSystem];
    _btn1.frame = CGRectMake(30, 250, 80, 40);
    [_btn1 setTitle:@"连接" forState:UIControlStateNormal];
    [_btn1 setTitle:@"断开" forState:UIControlStateSelected];
    [_btn1 addTarget:self action:@selector(createThread) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_btn1];
    
    UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeSystem];
    btn2.frame = CGRectMake(160, 250, 120, 40);
    [btn2 setTitle:@"发送消息" forState:UIControlStateNormal];
    [btn2 addTarget:self action:@selector(SendMessage) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn2];
}

//点击空白处收回键盘
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [_textField resignFirstResponder];
    [_textView resignFirstResponder];
}
-(void)createThread
{
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(link) object:nil];
    [thread start];
}
-(void)link
{
    [self linkHost];
}

//连接服务器
- (void)linkHost
{
    [_btn1 setSelected:!_btn1.selected];
    if (_btn1.selected)
    {
        //创建socket
        _SocketFD = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        
        if (-1 == _SocketFD)
        {
            perror("cannot create socket");
            exit(1);
        }

        struct sockaddr_in addr4;
        //初始化内存
        memset(&addr4, 0, sizeof(addr4));
        //设置socket地址协议族
        addr4.sin_family = AF_INET;
        //设置端口号
        addr4.sin_port = htons(5000);
        
        NSString *ipStr = _IPtextField.text;
        const char *ipCString = [ipStr cStringUsingEncoding:NSUTF8StringEncoding];
        int result = inet_pton(AF_INET, ipCString, &addr4.sin_addr);
        //转换ip地址出错
        if (result < 0) {
            NSLog(@"转换错误");
            close(_SocketFD);
            exit(1);
        }else if (result == 0){
            NSLog(@"char string (second parameter does not contain valid ipaddress)");
            close(_SocketFD);
            exit(1);
        }
        result = connect(_SocketFD, (struct sockaddr *)&addr4, sizeof(addr4));
        /* 出错处理 */
        if (result == -1)
        {
            perror("connect failed");
            close(_SocketFD);
            exit(1);
        }
        while (1) {
            //************
            //建立数据缓冲区
            char readBuffer[1024];
            int  br = 0;
            while ((br = recv(_SocketFD, readBuffer, sizeof(readBuffer), 0)) < sizeof(readBuffer) && br != 0)
            {
               // NSLog(@"==========");
                readBuffer[br] = '\0';
                NSString *bufferString = [NSString stringWithCString:readBuffer encoding:NSUTF8StringEncoding];
                
                [self performSelectorOnMainThread:@selector(receiveMessage:) withObject:bufferString waitUntilDone:NO];
                memset(readBuffer, 0, 1024);
                
            }
        }
        
    }
}
-(void)SendMessage
{
    NSString *ipStr = @"192.168.2.110";
    NSString *ipStr2 = @"192.168.2.134";
    NSString *str = [ipStr stringByAppendingString:_textField.text];
   
    const char *message = [str UTF8String];
      //发送数据
    send(_SocketFD, message, strlen(message), 0);
       
    
    _textField.text = @"";
}

-(void)receiveMessage:(NSString *)string
{
    string = [string stringByAppendingString:@"\n"];
    [_textView insertText:string];
}



服务器端
同上导入相关的类和头文件
实现代码如下
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.navigationController.navigationBar.translucent = NO;
    //_dic = [NSDictionary dictionary];
    
    [self setBtn];
    
    
}
-(void)setBtn
{
    
    _textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 280, 40)];
    _textField.delegate = self;
    _textField.borderStyle = UITextBorderStyleRoundedRect;
    _textField.placeholder = @"请输入发送消息";
    [self.view addSubview:_textField];
    
    
    _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 190, 320, self.view.frame.size.height) style:UITableViewStylePlain];
    _tableView.delegate = self;
    _tableView.dataSource = self;
    [self.view addSubview:_tableView];
    
    
    
    _textView = [[UITextView alloc] initWithFrame:CGRectMake(100, 80, 200, 80)];
    _textView.delegate = self;
    _textView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:_textView];
    
    _btn1 = [UIButton buttonWithType:UIButtonTypeSystem];
    _btn1.frame = CGRectMake(5, 80, 80, 40);
    [_btn1 setTitle:@"启动服务器" forState:UIControlStateNormal];
    [_btn1 setTitle:@"启动成功" forState:UIControlStateSelected];
    [_btn1 addTarget:self action:@selector(createThread) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_btn1];
    
    UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeSystem];
    btn2.frame = CGRectMake(5, 130, 80, 40);
    [btn2 setTitle:@"发送消息" forState:UIControlStateNormal];
    [btn2 addTarget:self action:@selector(SendMessage) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn2];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    cell.textLabel.text = [_listArray[indexPath.row] stringValue];
    return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _listArray.count;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    _ConnectFD = [_listArray[indexPath.row] intValue];
    
}

//点击空白处收回键盘
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [_textField resignFirstResponder];
    [_textView resignFirstResponder];
}
-(void)createThread
{
//    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(link) object:nil];
//    [thread start];
    [NSThread detachNewThreadSelector:@selector(linkHost) toTarget:self withObject:nil];
}
-(void)link
{
    [self linkHost];
}
//连接服务器
- (void)linkHost
{
    [_btn1 setSelected:!_btn1.selected];
    if (_btn1.selected)
    {
        //创建socket
        _SocketFD1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        
        if (-1 == _SocketFD1)
        {
            perror("cannot create socket");
            exit(1);
        }
        int yes = 1;
        if (setsockopt(_SocketFD1, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
        {
            perror("setsockopt error!");
            exit(1);
        }
        //创建Socket address结构体
        struct sockaddr_in addr4;
        //初始化内存
        memset(&addr4, 0, sizeof(addr4));
        //设置socket地址协议族
        addr4.sin_family = AF_INET;
        //设置端口号
        addr4.sin_port = htons(5000);
        
        //设置ip 地址
        addr4.sin_addr.s_addr = htonl(INADDR_ANY);
        //socket 套接字和指定的socket地址进行绑定
        if (-1 == bind(_SocketFD1, (struct sockaddr *)&addr4, sizeof(addr4)))
        {
            NSLog(@"绑定地址失败");
            close(_SocketFD1);
            exit(1);
        }
        if (-1 == listen(_SocketFD1, 10))
        {
            NSLog(@"监听失败");
            close(_SocketFD1);
            exit(1);
        }
        while (1)
        {
            //创建Socket address结构体
            struct sockaddr_in address;
            unsigned int addr = sizeof(address);
            _ConnectFD = accept(_SocketFD1,(struct sockaddr *)&address,&addr);
           // NSLog(@"------------%u",addr);
            //获取客户端的ip地址
            char *str = inet_ntoa(address.sin_addr);
           // NSLog(@"*****------%s",str);
            NSString *ipstr = [[NSString alloc] initWithCString:str encoding:NSUTF8StringEncoding];
            NSLog(@"*****%@",ipstr);
            if (0 > _ConnectFD)
            {
                NSLog(@"接收失败");
                close(_SocketFD1);
                exit(1);
            }else
            {
                if(!_listArray){
                    self.listArray = [NSMutableArray array];
                }
                if (!_ipArray) {
                    self.ipArray = [NSMutableArray array];
                }
                
                [_listArray addObject:[NSNumber numberWithInt:_ConnectFD]];
                [_ipArray addObject:ipstr];
                _dic = [[NSDictionary alloc] initWithObjects:_ipArray forKeys:_listArray];
                NSLog(@"%@",_dic);
                [_tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
                [self performSelectorInBackground:@selector(aa:) withObject:[NSNumber numberWithInt:_ConnectFD]];
                NSLog(@"接收成功");
            }
        }
    }
        
}

-(void)aa:(NSNumber *)ConnectID
{
    char readBuffer[1024];
    int  br = 0;
    while ((br = recv([ConnectID intValue], readBuffer, sizeof(readBuffer), 0)) < sizeof(readBuffer)&& br != 0)
    {
        readBuffer[br] = '\0';
        NSString *bufferString = [NSString stringWithCString:readBuffer encoding:NSUTF8StringEncoding];
        if([_listArray count] > 1)
        {
            int current =[ConnectID intValue];
//            int a =[_listArray[0] intValue];
//            int b =[_listArray[1] intValue];
            
            //NSLog(@"-------%@",bufferString);
            //标准是客户端的发送内容前面是目标iP地址,拼接发送给目标的信息
            static NSString * IPRegex = @"^(\\d{1,3}\\.){3}\\d{1,3}";//验证ip地址
            NSError *error;
            NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:IPRegex options:0 error:&error];
            NSString *msgStr;
            NSString *result;
            if (regex != nil) {
                NSTextCheckingResult *firstMatch=[regex firstMatchInString:bufferString options:0 range:NSMakeRange(0, [bufferString length])];
                
                if (firstMatch) {
                    NSRange resultRange = [firstMatch rangeAtIndex:0];
                    NSLog(@"%lu",(unsigned long)resultRange.location);
                   
                    
                    //从urlString当中截取数据
                     result = [bufferString substringWithRange:resultRange];
                    //输出结果
                    NSLog(@"----------%@",result);//目标ip地址
                    msgStr = [bufferString substringFromIndex:resultRange.length];
                    NSLog(@"*******%@",msgStr); //发送的内容
                }  
                
            }
            
            const char * ch = [msgStr UTF8String];
            for (int i = 0; i < _listArray.count; i++) {
                int temp = [_listArray[i] intValue];
                if (current != temp && [result isEqualToString:[_dic objectForKey:_listArray[i]]]) {
                    send(temp, ch, strlen(ch), 0);
                }
                
            }
//            const char * ch = [bufferString UTF8String];
//            if(current != a)
//                send(a, ch, strlen(ch), 0);
//            else
//                send(b, ch, strlen(ch), 0);
            
        }else{
            send([ConnectID intValue],[bufferString UTF8String], strlen([bufferString UTF8String]), 0);
            
        }
        
        //[self performSelectorOnMainThread:@selector(updateReceiveView:) withObject:bufferString waitUntilDone:NO];
        
    }
    
}


/* 获得本机ip */
- (NSString *)deviceIPAdress
{
    InitAddresses();
    GetIPAddresses();
    GetHWAddresses();
    return [NSString stringWithFormat:@"%s", ip_names[1]];
}

-(void)SendMessage
{
    NSString *message = _textField.text;
    const char *cmessage =[message UTF8String];
    //[message cStringUsingEncoding:NSUTF8StringEncoding];
    send(_ConnectFD, cmessage, strlen(cmessage), 0);
    _textField.text = @"";
}
-(void)updateReceiveView:(NSString *)string
{
    string = [string stringByAppendingString:@"\n"];
    [_textView insertText:string];
}



实现简单的socket通信,不足之处还望大家理解与补充。


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!