即时通讯(II)
阅读原文时间:2023年07月11日阅读:1

Socket 连接Demo

#import "ViewController.h"
//0、导入头文件
#include
#include
#include

static const char *serevr_ip = "127.0.0.1";
static const short server_port = ;

@interface ViewController ()

@property (assign, nonatomic) int clientSocket;

@property (weak, nonatomic) IBOutlet UITextField *msgTextField;
@property (strong, nonatomic) IBOutletCollection(UITextView) NSArray *chatTextView;

@end

@implementation ViewController

  • (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self initSocket];
    }

  • (void)initSocket{
    //1、创建 Socket

    /*
    参数
    第一个参数: adress_family,协议簇 AF_INET ---> IPV4(本地主机通讯) IPV6 AF_UNIX(本地主机通讯,linux使用)
    第二个参数: 数据格式----> SOCK_STREAM(TCP)/SOCK_DGRAM(UDP);TCP基于数据流传输,UDP基于数据报文传输
    第三个参数: protocol IPPROTO_TCP,如果传入 0 ,会自动根据第二个参数,选中合适的协议;服务端自动给你确认需要什么协议
    返回值: 成功 -----> 正值 失败 -------> -1
    */

    _clientSocket = socket(AF_INET, SOCK_STREAM, );

    //2、连接服务器
    struct sockaddr_in sAddr = {};

    sAddr.sin_len = sizeof(sAddr);//长度

    inet_aton(serevr_ip, &sAddr.sin_addr); //字节序,分为:主机字节序(整数在主机中存放的顺序)和网络字节序。

    sAddr.sin_port = htons(server_port);

    sAddr.sin_family = AF_INET; //协议簇

    /*
    第一个参数: 客户端 Socket

    第二个参数: 指向数据结构 sockeAddr 的指针,其中包括目的端口和 IP地址

    第三个参数: 结构体数据长度

    返回值:成功 ----> 0 其他 ----> 错误代号
    */
    int connectFlag = connect(_clientSocket, (struct sockaddr *)&sAddr, sizeof(sAddr));

    if (connectFlag == ) {
    //开启线程后要开为一个长度线程
    NSThread *thread = [[NSThread alloc] initWithTarget:self
    selector:@selector(receiveAction) object:nil];
    [thread start];

    }else{
    NSLog(@"连接错误");

    }
    }

  • (void)receiveAction{
    while () {
    //内容缓存区
    char rec_msg[] = {};

     /\*\*  
      监听服务端发送的数据
    
      @param \_clientSocket 客户端Socket  
      @param rec\_msg 发送内容地址,内容缓存区  
      @param rec\_msg 发送内容长度  
      @param rec\_msg 发送方式标识,一般为 0  
      @return 成功---> 返回字节数,失败---->SOCKET-ERROR  
      \*/  
     recv(\_clientSocket, rec\_msg, sizeof(rec\_msg), );  
     printf("----->%s\\n",rec\_msg);  

    }
    }

  • (void)sendMessage:(NSString *)msg{
    const char *send_Message = [msg cStringUsingEncoding:NSUTF8StringEncoding];
    send(_clientSocket,send_Message,strlen(send_Message) ,);
    }

  • (IBAction)sendAction:(UIButton *)sender {
    if ([_msgTextField.text isEqualToString:@""]) {
    NSLog(@"发送消息不能为空");
    return;
    }
    [self sendMessage:_msgTextField.text];
    }

  • (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    }

    @end

TCP连接以后进行通讯可能会发生丢包事件,这时客户端和服务器端就要进行一定的约定,定义一些 “/n” 之类的一些标识符。

打开一个终端端口,输入:

nc -l 6969 //监听客户端数据的发送

然后运行客户端的程序代码,否则控制台会打印:"连接错误";

在模拟器中输入:33333

终端也会出现:33333

在终端输入:-----》》》welcome  即时通讯

在程序的控制台会打印:

终端如图:

Socket服务器端代码

代码图一:

代码图二:

代码图三:

代码图四:

代码图五:

面试题:

Socket 监听一个端口,最多有多少个连接?

与客户端最多有1024个连接,但同时能连接的请求最多5个。

服务器同一时刻,一个端口只能建立一个连接服务端,但是它会生成一个等待队列,每一个请求它都会放在这个请求队列里,根据某一算法在某一时刻处理哪个请求。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章