Socket通信理解


要了解Socket,我们就必须要和http一起来了解,看看二者的区别和异同,

一. socket连接 和 http连接 的区别

简单说,你浏览的网页(网址以 "http://开头" ) 都是http协议传输到你的浏览器的, 而http是基于socket之上的。socket是一套完成TCP,UDP协议的接口。

1. 关于协议

HTTP协议:简单对象访问协议,对应于应用层 ,同时HTTP协议也是基于TCP连接的;主要解决如何包装数据。
TCP协议: 对应于传输层
ip协议: 对应于网络层TCP/IP是传输层协议,主要解决数据如何在网络中传输;

Socket:是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。

2. 关于连接

http连接:http连接就是所谓的短连接,即客户端向服务器端发送一次请求,服务器端响应后连接即会断掉;
socket连接:socket连接就是所谓的长连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉;但是由于各种环境因素可能会是连接断开,比如说:服务器端或客户端主机down了,网络故障,或者两者之间长时间没有数据传输,网络防火墙可能会断开该连接以释放网络资源。所以当一个socket连接中没有数据的传输,那么为了维持连接需要发送心跳消息~~具体心跳消息格式是开发者自己定义的

3.我们已经知道网络中的进程是通过socket来通信的,那什么是socket呢?

socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。
我的理解就是Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。
我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如HTTP、FTP、TELNET等,也可以自己定义应用层协议。
WEB使用HTTP协议作应用层协议,以封装HTTP文本信息,然后使用TCP/IP做传输层协议将它发到网络上。

4. 总的来说
  1. Socket是一个针对TCP和UDP编程的接口,你可以借助它建立TCP连接等等。而TCP和UDP协议属于传输层 。 http是个应用层的协议,它实际上也建立在TCP协议之上。
    (HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。)
    2)Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口。

二. 什么是 TCP 连接的三次握手

第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。
理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去(也就是长连接)。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”(过程就不细写了,就是服务器和客户端交互,最终确定断开)

三. 那么利用 Socket 建立网络连接的步骤是什么?

建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
1。服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
2。客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
3。连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

四. 简单演示

0.导入头文件

#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>

1 创建Socket

int clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

//参数解析
    //第一个参数 domain 协议簇  指定IPv4
    //第二个参数 type   socket的类型  流socket  数据报socket
    //第三个参数 protocol  协议    
    //返回值 如果创建成功返回的是socket的描述符,失败-1

2 连接服务器

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(12345);
    int result = connect(clientSocket, (const struct sockaddr *) &addr, sizeof(addr));
// 参数解析:
    //第一个参数 socket的描述符
    //第二个参数 结构体 ip地址和端口
    //第三个参数 结构体的长度 sizeof
    //返回值 成功0  失败非0
 if (result != 0) {
        NSLog(@"失败");
        return;
    }

3 向服务器发送数据

const char *msg = "hello world";
   ssize_t sendCount = send(clientSocket, msg, strlen(msg), 0);
   NSLog(@"发送的字节数 %zd",sendCount);
//参数解析:
   //成功则返回实际传送出去的字符数,失败返回-1
   // strlen(msg) 注意: 第三个参数是字符数,而不是字节数sizeof

4 接收服务器返回的数据

 //返回的是实际接收的字节个数   ----> 注意:这里是字节数,不是字符数
    uint8_t buffer[1024]; // ----> 这是一个字节数组
    ssize_t recvCount = recv(clientSocket, buffer, sizeof(buffer), 0);
    NSLog(@"接收的字节数 %zd",recvCount);
    
    //把字节数组转换成字符串
    // 先将字节数组转换成二进制数据, 然后再转换成字符串
    NSData *data = [NSData dataWithBytes:buffer length:recvCount];
    NSString *recvMsg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"shoudao : %@",recvMsg);
    

5 关闭连接

close(clientSocket);

Socket的使用我这里只列举了很简单的一种, 更为复杂的,大家可以自行学习, 总体来说, 只要是涉及到通讯类的应用,都是需要使用Socket, 最著名的就是我们常用的QQ,微信,旺旺等,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值