zoukankan      html  css  js  c++  java
  • 即时通讯(II)

    Socket 连接Demo

    Socket客户端代码

      1 #import "ViewController.h"
      2 //0、导入头文件
      3 #include <netinet/in.h>
      4 #include <sys/socket.h>
      5 #include <arpa/inet.h>
      6 
      7 static const char *serevr_ip = "127.0.0.1";
      8 static const short server_port = 6969;
      9 
     10 @interface ViewController ()
     11 
     12 @property (assign, nonatomic) int clientSocket;
     13 
     14 @property (weak, nonatomic) IBOutlet UITextField *msgTextField;
     15 @property (strong, nonatomic) IBOutletCollection(UITextView) NSArray *chatTextView;
     16 
     17 @end
     18 
     19 @implementation ViewController
     20 
     21 - (void)viewDidLoad {
     22     [super viewDidLoad];
     23     // Do any additional setup after loading the view, typically from a nib.
     24     [self initSocket];
     25 }
     26 
     27 - (void)initSocket{
     28   //1、创建 Socket
     29     
     30     /*
     31      参数
     32      第一个参数: adress_family,协议簇 AF_INET ---> IPV4(本地主机通讯)    IPV6   AF_UNIX(本地主机通讯,linux使用)
     33      第二个参数: 数据格式----> SOCK_STREAM(TCP)/SOCK_DGRAM(UDP);TCP基于数据流传输,UDP基于数据报文传输
     34      第三个参数: protocol  IPPROTO_TCP,如果传入 0 ,会自动根据第二个参数,选中合适的协议;服务端自动给你确认需要什么协议
     35      返回值: 成功 -----> 正值   失败 -------> -1
     36      */
     37     
     38     _clientSocket = socket(AF_INET, SOCK_STREAM, 0);
     39     
     40     //2、连接服务器
     41     struct sockaddr_in sAddr = {0};
     42     
     43     sAddr.sin_len = sizeof(sAddr);//长度
     44     
     45     inet_aton(serevr_ip, &sAddr.sin_addr);  //字节序,分为:主机字节序(整数在主机中存放的顺序)和网络字节序。
     46     
     47     sAddr.sin_port = htons(server_port);
     48     
     49     sAddr.sin_family = AF_INET; //协议簇
     50     
     51     /*
     52      第一个参数: 客户端 Socket
     53      
     54      第二个参数: 指向数据结构 sockeAddr 的指针,其中包括目的端口和 IP地址
     55      
     56      第三个参数: 结构体数据长度
     57      
     58      返回值:成功 ----> 0  其他 ----> 错误代号
     59      */
     60     int  connectFlag = connect(_clientSocket, (struct sockaddr *)&sAddr, sizeof(sAddr));
     61     
     62     if (connectFlag == 0) {
     63         //开启线程后要开为一个长度线程
     64         NSThread *thread = [[NSThread alloc] initWithTarget:self
     65                                                    selector:@selector(receiveAction) object:nil];
     66         [thread start];
     67         
     68     }else{
     69         NSLog(@"连接错误");
     70         
     71     }
     72 }
     73 
     74 
     75 - (void)receiveAction{
     76     while (1) {
     77         //内容缓存区
     78         char rec_msg[1024] = {0};
     79         
     80         /**
     81          监听服务端发送的数据
     82 
     83          @param _clientSocket 客户端Socket
     84          @param rec_msg 发送内容地址,内容缓存区
     85          @param rec_msg 发送内容长度
     86          @param rec_msg 发送方式标识,一般为 0
     87          @return 成功---> 返回字节数,失败---->SOCKET-ERROR
     88          */
     89         recv(_clientSocket, rec_msg, sizeof(rec_msg), 0);
     90         printf("----->%s
    ",rec_msg);
     91     }
     92 }
     93 
     94 - (void)sendMessage:(NSString *)msg{
     95     const char *send_Message = [msg cStringUsingEncoding:NSUTF8StringEncoding];
     96     send(_clientSocket,send_Message,strlen(send_Message) ,0);
     97 }
     98 
     99 - (IBAction)sendAction:(UIButton *)sender {
    100     if ([_msgTextField.text isEqualToString:@""]) {
    101         NSLog(@"发送消息不能为空");
    102         return;
    103     }
    104     [self sendMessage:_msgTextField.text];
    105 }
    106 
    107 - (void)didReceiveMemoryWarning {
    108     [super didReceiveMemoryWarning];
    109     // Dispose of any resources that can be recreated.
    110 }
    111 
    112 
    113 @end
    View Code

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

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

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

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

    在模拟器中输入:33333

    终端也会出现:33333

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

    在程序的控制台会打印:

    终端如图:

    Socket服务器端代码

    代码图一:

     

    代码图二:

    代码图三:

    代码图四:

    代码图五:

    面试题:

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

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

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

  • 相关阅读:
    [已解决] MAVEN安装代码到本地库,安装jar, source, javadoc的方式
    [已解决]Eclipse 插件Maven在使用 add dependency,找不到包,解决办法
    [已解决] windows 下 git 免输密码
    [已解决] windows 80端口被占用
    [已解决]Tomcat启动报 java.net.BindException: Address already in use: JVM_Bind
    [已解决] java.net.InetAddress.getHostName() 阻塞问题
    [已解决] 日常开发中禁用Tomcat自动重启
    [已解决] MyBatis 中bind用法
    [转]SOCKET通信中TCP、UDP数据包大小的确定
    使用beautifulsoup与requests爬取数据
  • 原文地址:https://www.cnblogs.com/EchoHG/p/9191860.html
Copyright © 2011-2022 走看看