标签:const port 发送数据 握手 osi 游戏 tcp 简单 turn
了解socket,就需要了解数据在网络中传输。
网络通讯有三要素:ip地址,网络中设备的表示,例如本机用127.0.0.1,或者用本机名:localhost;端口号,用来标示进程的逻辑地址,也就是服务,有效端口0~65535,一般1024以下端口被系统或者本地服务所占据,开发中尽量不要使用,以避免冲突;通讯协议——UDP,TCP,UDP是用户数据报文协议,只负责发送数据,并不管是否被接收,不会建立联接,其会将数据和目的封装到数据包中。每个包大小为64K以内,数据传输速度很快,但是并不安全,一般用在游戏,直播之类的行业中;TCP则需要建立联接来传输数据,不会对数据做大小限制,需要通过三次握手协议来完成连接,安全可靠,缺点便是效率低。
三次握手建立连接:
首先client发送连接请求到服务器,服务器同意连接发送ACK报文,并为这次连接分配资源;client接收到ACK报文后,也向服务器发送ack报文,并为连接分配资源,这样TCP连接就建立成功。断开时采用四次挥手协议:
client发送断开连接请求,FIN报文,服务器接收到FIN报文了,知道client已经准备好结束连接,不再传输数据,但是如果服务器端没有准备好,不用着急关闭scoket,仍然可以发送数据前往client,此时需要发送ACK报文,告诉client请等待结束,让client进去FIN_WAIT状态。当服务器确定完成数据发送并可以关闭,发送FIN报文进入client,client接收到FIN报文后,并不会立刻断开连接,为了避免错误关闭状态,例如服务器没打算关闭连接,会向服务器发送ACK报文,并会进入TIME_WAIT状态,等待2MSL后未接收到服务器回应变正式断开连接,而服务器在接收到ACK报文后也会断开连接。
UDP会涉及到数据打包发送,这其中会需要了解osi七层模型:
进行数据传输,首先应用层形成源,然后在传输层通过TCP/UDP协议包装,在网络层,确定ip和端口号(形成socket),建立数据传输io,在数据链路层打包数据,每一包数据即为一帧,最后通过物理层转为电信号,电信号的传输标示采用高低电平,其实就是01数据,即二进制数据传输,所以网络中数据传输形式都是二进制。
了解这么多后,再来看socket概念。网络通信就是socket间的通信,需要两端都是socket,然后这两端建立IO传输。可以这样理解,socket是一种网络机制类,实例化的具体信息就是ip+端口。当我们使用qq聊天,a手机IP+qq端口发送信息,需要找到b手机IP+qq端口才能接收数据;
socket本身是用c语言书写,方便跨平台使用,使用起来也非常简单,基本可以归位五步。一步,创建socket,第二步,建立connect,第三步,write数据,第四步read数据,第五步colse;
首先,打开终端,输入命令:nc -lk 1025(监听端口号1025)
导入头文件:
#import <sys/socket.h> #import <netinet/in.h> #import <arpa/inet.h>
按操作创建socket连接:
1.创建socket
/** 参数 socket三个参数传入相应值 domain: 协议域,AF_INET -> IPV4 AF_INET6 -> IPV6 type: Socket 类型,SOCK_STREAM数据流/SOCK_DGRAM数据报文 protocol: IPPROTO_TCP,如果传入0 那么会自动根据第二个参数选择合适的协议 返回值 socket */ int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
2.连接服务器
/** 参数 1> 客户端socket 2> 指向数据结构sockaddr的指针,其中包括目的端口和IP地址 3> 结构体数据长度 返回值 0 成功/其他 错误代号 */ struct sockaddr_in severAddr; severAddr.sin_family = AF_INET; //端口 severAddr.sin_port = htons(1025); //地址 severAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); int connResult = connect(clientSocket, (const struct sockaddr *)&severAddr, sizeof(severAddr)); if (connResult == 0) { NSLog(@"连接成功!!"); }else{ NSLog(@"失败了 %d",connResult); return; }
3.write数据,写入hello world 可以在简单端口看到相应展示
/** 参数 1> 客户端socket 2> 发送内容地址 3> 发送内容长度 4> 发送方式标志,一般为0 返回值 如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR */ NSString * sendMsg =@"hello world"; ssize_t sendLen = send(clientSocket, sendMsg.UTF8String, strlen(sendMsg.UTF8String), 0);
4.read数据,在端口下写入me too可以看到xcode打印结果展示
/** 参数 1> 客户端socket 2> 接收内容缓冲区地址 3> 接收内容缓存区长度 4> 接收方式,0表示阻塞,必须等待服务器返回数据 返回值 如果成功,则返回读入的字节数,失败则返回SOCKET_ERROR */ uint8_t buffer[1024];//要把空间准备出来! ssize_t recvLen = recv(clientSocket, buffer, sizeof(buffer), 0);
5.最后便是便是关闭socket
close(clientSocket);
标签:const port 发送数据 握手 osi 游戏 tcp 简单 turn
原文地址:http://www.cnblogs.com/zhulilove/p/8016557.html