zoukankan      html  css  js  c++  java
  • Socket网络编程入门

    Socket:专业术语:套接字;通俗的解释:两孔插座(一个孔:IP地址,一个孔:端口号).使用场景:通信,如QQ好友交谈,如浏览器的进程怎么与web服务器通信等.

    Socket来历:

       socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。

       其中,这些socket函数的介绍请看这里:吴秦(Tyler)Socket编程

       在组网领域的首次使用是在1970年2月12日发布的文献IETF RFC33中发现的,撰写者为Stephen Carr、Steve Crocker和Vint Cerf。根据美国计算机历史博物馆的记载,Croker写道:"命名空间的元素都可称为套接字接口。一个套接字接口构成一个连接的一端,而一个连接可完全由一对套接字接口规定。”计算机历史博物馆补充道:"这比BSD的套接字接口定义早了大约12年。

        通过上面,我们知道了socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket,另一个运行于服务器端,称为ServerSocket。套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接,UDP连接同理。

     网络七层协议:  

         网络七层协议由下往上分别为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。其中物理层、数据链路层和网络层通常被称作媒体层,是网络工程师所研究的对象;传输层、会话层、表示层和应用层则被称作主机层,是用户所面向和关心的内容。

         HTTP协议对应于应用层,TCP协议对应于传输层,IP协议对应于网络层,HTTP协议是基于TCP连接的,三者本质上没有可比性。 TCP/IP是传输层协议,主要解决数据如何在网络中传输;而HTTP是应用层协议,主要解决如何包装数据。Socket是应用层与TCP/IP协议族通信的中间软件抽象层,是它的一组接口。

    其图示如下:

    而其中TCP,UDP协议的区别如下:

    而,建立TCP连接需要经过"三次握手",断开连接需要"四次握手".这就是当初大学天天背诵而不知干嘛的"三次握手,四次分手"原则(至今也才懵懵懂懂).

      

     Socket通信就是依靠这完成的,其中通讯示意图如:

    以上就是一些基本的知识点,下面写一个小demo演示下:

    //
    //  ViewController.m
    //  Socket入门
    //
    //  Created by Shaoting Zhou on 2017/4/17.
    //  Copyright © 2017年 Shaoting Zhou. All rights reserved.
    //   nc -lk 12345  监听12345端口
    
    #import "ViewController.h"
    #import <sys/socket.h>
    #import <netinet/in.h>
    #import <arpa/inet.h>
    
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self socketDemo];
    }
    
    
    //MARK : Socket演练
    - (void)socketDemo {
        //1.创建Socket
        /**
         参数
         
         domain:    协议域,AF_INET --> IPV4
         type:      Socket 类型,SOCK_STREAM(TCP)/SOCK_DGRAM(UDP)
         protocol: IPPROTO_TCP, 如果传入0,会自动更具第二个参数,选择合适的协议
         
         返回值
         socket
         */
        int  clientSocket = socket(AF_INET, SOCK_STREAM, 0);
        //2.连接到服务器
        /**
         参数
         1> 客户端socket
         2> 指向数据结构体sockaddr的指针,其中包括目的端口和IP地址
         3> 结构体数据长度
         返回值
         0 成功/其他 错误代号
         */
        //结构体  sockaddr
        struct sockaddr_in serverAddr;
        //协议域
        serverAddr.sin_family = AF_INET;
        //端口号
        serverAddr.sin_port = htons(12345);     //定义一个端口号演示
        //IP地址
        serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
        
        
        int connResult =  connect(clientSocket, (const struct sockaddr *)&serverAddr , sizeof(serverAddr));
        //3.发送数据给服务器
        /**  C语言里面  Void *  代表指向任意类型
         参数
         1> 客户端socket
         2> 发送内容地址(指针)
         3> 发送内容长度
         4> 发送方式标志,一般为0
         返回值
         如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR
         */
        NSString * sendMsg = @"shaoting";   //随意定义一个字符串演示
        
        ssize_t sendLen =  send(clientSocket, sendMsg.UTF8String, strlen(sendMsg.UTF8String), 0);
        NSLog(@"发送了 %ld 个字节",sendLen);
        
        //4.从服务器接收数据
        /**
         参数
         1> 客户端socket
         2> 接收内容缓冲区地址(指针)
         3> 接收内容缓存区长度
         4> 接收方式,0表示阻塞,必须等待服务器返回数据
         返回值
         如果成功,则返回读入的字节数,失败则返回SOCKET_ERROR
         */
        uint8_t buffer[1024];//空间准备出来
        
        ssize_t recvLen =   recv(clientSocket, buffer, sizeof(buffer), 0);
        NSLog(@"接收到了 %ld 个字节",recvLen);
        
        //获取服务器返回的数据,从缓冲区读取recvLen个字节!!!
        NSData * data = [NSData dataWithBytes:buffer length:recvLen];
        //二进制转字符串
        NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%@",str);
        
        
        
        //5.关闭
        close(clientSocket);
        
        
        
    }
    
    
    @end
    

     首先在终端运行 nc -lk 12345,监听着端口12345,启动Xcode项目,这时会连上本地服务器127.0.0.1,然后就会发送刚才准备的字符串(shaoting),然后还可以从服务器发个消息到客户端.演示效果如:

    本文demo地址:https://github.com/pheromone/iOS-Scoket-

    当然,大家应该还听说过XMPP协议,这个就是在Scoket基础上得来的.这个是当初学习XMPP的demo地址:https://github.com/pheromone/iOS-XMPPDemo

    在此,感谢大神博客   吴白 

              吴秦(Tyler)

              百度运维博文精选Https对性能的影响

              腾讯课堂某公开课  

                                                  

     

     

  • 相关阅读:
    UE4中集成ProtoBuf
    QT之打印 QPrinter
    qt界面嵌入外部进程界面
    QAxWidget 妙用
    UE4嵌入Qt5 三维可视化案例
    QSS入门(一)
    Docker与k8s的恩怨情仇(四)-云原生时代的闭源落幕
    成品软件二次开发排第三,低代码的应用场景有哪些?
    React 并发功能体验-前端的并发模式已经到来。
    Docker与k8s的恩怨情仇(三)—后浪Docker来势汹汹
  • 原文地址:https://www.cnblogs.com/shaoting/p/6722796.html
Copyright © 2011-2022 走看看