网络聊天室一 --- socket的简单使用用C语言编写(实现客户端与服务器简单通信)

网络聊天室(socket简单聊天)

网络聊天室一 --- socket的简单使用用C语言编写(实现客户端与服务器简单通信)

关键代码如下:

一、连接

1.socket连接

- (IBAction)socketConnect:(id)sender {
//0.这里使用已经用python写好的服务器进行测试,在终端里cd到服务器代码的位置,然后开始启动它 python 服务器文件名
//1.三次握手,通过ip和端口号。
//2.使用c语言编写输入输出流,并分配输入输出流的内存空间
//3.转换成oc的输入输出流。
//4.加到主运行循环中,主运行监听网络
//5.打开输入输出流
  
    NSString *host = @"127.0.0.1";
    int post = 12345;
    CFReadStreamRef readStream; //输入流
    CFWriteStreamRef writeStream; //输出流
    //为输入输出流的内存空间
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)(host), post, &readStream, &writeStream);
    
    _inputStream = (__bridge NSInputStream *)readStream;
    _outStream = (__bridge NSOutputStream *)writeStream;
    _inputStream.delegate = self;
    _outStream.delegate = self;
    //加到主运行循环中
    [_inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [_outStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    //打开
    [_inputStream open];
    [_outStream open];
}

2.socket代理回调

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
//    NSStreamEventOpenCompleted = 1UL << 0,
//    NSStreamEventHasBytesAvailable = 1UL << 1,
//    NSStreamEventHasSpaceAvailable = 1UL << 2,
//    NSStreamEventErrorOccurred = 1UL << 3,
//    NSStreamEventEndEncountered = 1UL << 4
    switch (eventCode) {
        case NSStreamEventOpenCompleted:
            NSLog(@"成功连接,形成输入输出流通道");
            break;
        case NSStreamEventHasBytesAvailable:
            NSLog(@"有数据可读");
            
            [self readData];
            break;
            
        case NSStreamEventHasSpaceAvailable:
            NSLog(@"可以发送数据");
            break;
            
        case NSStreamEventErrorOccurred:
             NSLog(@"有错误发生连接失败");
            
            break;
            
        case NSStreamEventEndEncountered:
            NSLog(@"正常结束连接");
            break;
            
        default:
            break;
    }
}

二、登录

//发送登录指令,使用输出流
//拼接登录指令 iam:登录信息,服务器那边规定登录以iam:开头
    NSString *loginStr = @"iam:zhangSan";
    
    [self sendData:loginStr];

三、发送信息

1.发送信息

- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    
    
    NSString *msg = textField.text;
    if (msg.length)  return YES;
    //服务器那边规定聊天时以msg:开头
    [self sendData:[@"msg:" stringByAppendingString:msg]];
    return YES;
}
- (void)sendData:(NSString *)sendMsg{
    //unit_8 字符(char型)+ * 就是字符串
    NSData *data = [sendMsg dataUsingEncoding:NSUTF8StringEncoding];
    [_outStream write:data.bytes maxLength:data.length];  
}

2.键盘处理

    //监控键盘的弹出和隐藏
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kdWillShow:) name:UIKeyboardWillShowNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kdWillHide:) name:UIKeyboardWillHideNotification object:nil];
#pragma mark --- keyboard handle
- (void)kdWillShow:(NSNotification *)noti{
    CGFloat kdHeight = [noti.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height;
    self.viewBottmConstraints.constant = kdHeight;
    
}
- (void)kdWillHide:(NSNotification *)noti{
    self.viewBottmConstraints.constant = 0;
}
- (void)dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

四、读取消息和显示消息

//read data
- (void)readData{
    //创建缓冲区,比如说一个杯子可以装多少水,规定一下
    
    uint8_t buf[1024];
    //读取数据,len是服务器读取的实际字节数
    NSUInteger len = [_inputStream read:buf maxLength:sizeof(buf)];
    //把缓冲区的实际字节数转换成字符串
    NSString *readStr = [[NSString alloc] initWithBytes:buf length:len encoding:NSUTF8StringEncoding];
    NSLog(@"%@",readStr);
    [self.msgs addObject:readStr];
    [self.tableView reloadData];
    
}