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
在此,感谢大神博客 吴白
腾讯课堂某公开课