SCOKET、HTTP、XMPP、TCP、UDP之间的关系
HTTP和XMPP都是应用层的协议,是对数据的包装,TCP/UDP是传输层的协议,而SCOKET是一套连接应用层与传输层的接口。
SCOKET不是协议,是一套介于应用层与传输层的API,SCOKET是对TCP/IP协议(或者UDP/IP协议)的封装,通过SCOKET我们才能使用TCP/IP协议(或者UDP/IP协议)。SCOKET又称"套接字”,网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个SCOKET。应用程序通常通过"套接字"向网络发出请求或者应答网络请求
XMPP请求的模式就是TCP长连接,每一次长链接都需要三次握手,性能很低,所以可以在每次要断开连接的时候发送一点垃圾数据(心跳包),将连接保持下去,不需要再连接了,就是长连接了。
HTTP请求的模式就是UDP短连接,由于HTTP请求完一次不知道下次请求的时间,所以要断开连接,保证设备的性能。
建立SCOKET连接
(1)建立SCOKET连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket,另一个运行于服务器端,称为ServerSocket。
(2)套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
- 服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
- 客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
- 连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发 给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
SOCKET连接与TCP连接
创建SCOKET连接时,可以指定使用的传输层协议,SCOKET可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该SCOKET连接就是一个TCP连接。
SOCKET连接与UDP连接
由于通常情况下SCOKET连接就是TCP连接,因此SCOKET连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。
服务端接收到scoket的过程服务器端:首先必须创建一个服务器的socket,有客户端访问的时候,就会收到客户端的socket,由于客户端的socket是局部变量,所以需要一个数组去存储,这样在服务器端就会有客户端的socket(相当于复制了客户端的socket),实际上服务器的socket只做了一件事,剩下的都是两个客户端的socket在服务器与客户端之间进行通信//初始化socketself.serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];// 绑定端口1025~[self.serverSocket acceptOnPort:4000 error:&error];// 接收到一个新的socket,就会来到这个方法// @params sock 服务端的sock// @params newSocket 客户端的socket- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket;//读取到数据,就会来到这个方法(返回的是客户端的socket)// @params sock 服务端的sock// @params data 服务器接收到的数据- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;//发送给客户端信息// @params data 服务器发送给客户端的数据// @params timeout// @params tag- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;// (再次)进入读取状态// @params timeout// @params tag- (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;//服务器发送数据成功会执行这个方法(返回的是客户端的socket)// @params sock 服务端的sock// @params tag- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag;//断开连接或者连接失败(返回的是客户端的socket)// @params sock 服务端的sock// @params err- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err;
客户端收到Socket// 绑定//初始化// @params self.clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];//连接服务器1.ip地址 2.端口[self.clientSocket connectToHost:@"" onPort:9999 error:&error];// 连接成功会走着个方法// @params sock // @params host// @params port- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{ //让socket处于等待状态,接收数据 [self.clientSocket readDataWithTimeout:-1 tag:0];}//接收数据成功会走这个方法// @params sock// @params data// @params tag- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;// 客户端发送给服务器的数据// @params datas // @params [self.clientSocket writeData:datas withTimeout:-1 tag:0];//让socket再次进入等待状态,接收数据[self.clientSocket readDataWithTimeout:-1 tag:0];//发送服务器成功走的方法// @params sock// @params tag- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag;//连接失败走到这里// @params sock// @params err- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err;//重连[self.clientSocket connectToHost:@"" onPort:9999 error:&error];
Intro
robbiehanson edited this page on 24 Nov 2011 ·
Pages 8
Clone this wiki locally
Introduction to Sockets
If you're a beginner to networking, this is the place to start. Working with a socket can be very different from working with a file, even though the APIs may be similar. A little bit of investment in your knowledge and understanding of networking fundamentals can go a long way. And it can save you a lot of time and frustration in the long run.
We will keep it brief, and will maintain a focus on developers: just what developers need to accomplish their goal, while not skipping important fundamentals that could later cause problems.
Sockets, Ports, and DNS - Oh My!
In networking parlance, a computer is a host for a number of sockets. A socket is one end of a communication channel called a network connection; the other end is another socket. From its own point of view, any socket is the local socket, and the socket at the other end of the connection is the remote socket.
To establish the connection, one of the two sockets must contact the other socket. To make contact the socket must know the other socket's address. Every socket has an address. The address consists of two parts: the host address and the port number. The host address is the IP address of the computer, and the port number uniquely identifies each socket hosted on the computer.
A computer can have multiple host addresses because it can have multiple networking interfaces. For example, a computer might be equipped with an ethernet card, a modem, a WiFi card, a VPN connection, Bluetooth, etc. And in addition to all this, there is a special interface for connecting to itself (called "loopback" or sometimes “localhost”).
An address such as “google.com” corresponds to a host address, but it is not a host address itself. It is a DNS entry or DNS name, which is converted to a host address by a DNS look-up operation. One can think of DNS like a phone book. If you wanted to call someone, but didn't know their number, you could lookup their number in the phone book. Their name is matched to a phone number. Similarly, DNS matches a name (such as "google.com") to an IP address.
Networking Huh?
The crux of the problem is that the network you'll be communicating over is unreliable. Perhaps you're sending data out over the Internet. Maybe it's going to be sent via WiFi, or some cellular connection. Or maybe it's going to be sent into space via a satellite. You might not even know.
But let's assume for a moment that you did know. Let's assume you knew that all communication was going to take place over regular ethernet, within a closed business network. The communication would be 100% reliable right? Wrong. And I'm not referring to cut wires or power outages either.
All data that gets sent or received gets broken into little packets. These packets then get pumped onto the network, and arrive at routers which have to decide where they go. But during bursts of traffic, a router might get overloaded with packets. Packets are coming in faster than the router can figure out where to route them. What happens? The same thing that happens millions of times a day all over the world: the router starts dropping packets.
In addition to lost packets on the network, the receiving computer might be forced to drop packets too. Perhaps the computer is overloaded, or the receiving application isn't reading the data from the OS fast enough. There's also the potential that the packet was corrupted during transmission, perhaps from electrical interference. And all of this is without getting into other issues introduced by things like the WiFi or the Internet.
If you're new to networking, you might be thinking that it's a miracle that everything works as well as it does. The fact is, the miracle is derived from the networking protocols that have been perfected over the last several decades, and from the developers that understand them and use them effectively. (That's you!)
Bring on the Protocols
You can probably list dozens of protocols that have something to do with computer networking:
HTTP, FTP, XMPP, POP, IMAP, SMTP, DHCP, DNS, VoIP, SIP, RTP, RTCP, ...
But every single one of these protocols is layered on top of another protocol that handles the networking for it. These lower level protocols handle the majority of the networking aspect so that the application layer protocol (those listed above) can focus on the application aspect.
The "application layer protocols" listed above are layered on top of a "transport layer protocol". And of all the protocols listed above, there are only two transport layer protocols that are used: TCP and UDP.
UDP
The User Datagram Protocol (UDP) is the simpler of the two. You can only put a small amount of data into a UDP packet, and then you send it on its way. And then... that's it. There is no guarantee that the message will arrive. And if you send multiple packets back-to-back, there is no guarantee that they will arrive in order. Seems pretty unreliable, no? But it's weakness is also its strength. If you are sending time-sensitive data, such as audio in a VoIP call, then you don't want your transport protocol wasting time retransmitting lost packets since the lost audio would arrive too late to be played anyway. In fact, streaming audio and video are some of the biggest uses for UDP.
UDP also has an advantage that it doesn't require a "connection handshake". Think about it like this: If you were sitting on a train, and you wanted to have a long conversation with the stranger next to you, you would probably start with an introduction. Something like, "Where are you heading? Oh yeah, I'm heading in that direction too. My name's Robbie, what's yours?" But if you just wanted to know what the time was, then you could skip the introduction. You wouldn't be expected to tell the stranger your name. You could just say, "Excuse me, do you have the time?" To which the stranger could quickly respond, and you could both go back to doing whatever you were doing. This is why a protocol like DNS uses UDP. That way your computer can say, "Excuse me, what is the IP of google.com?" And the server can quickly respond.
TCP
The Transmission Control Protocol (TCP) is probably the protocol you use the most. Whether you're browsing the web, checking your email, or sending instant messages to friends, you're probably using TCP.
TCP is designed for "long conversations". So there is an initial connection handshake, and after that data can flow back and forth for as long as necessary. But the great thing about TCP is that it was designed to make communication reliable in the face of an unreliable network. So it does all kinds of really cool stuff for us. If you send some information over TCP, and part of it gets lost, the protocol will automatically figure out what got lost and resend it. And when you send information, TCP makes sure that information always arrives in the correct order. But wait, there's more! The protocol will also detect congestion in the network, and automatically scale accordingly so everybody can share.
So there are a lot of great reasons to use TCP, and it fits in nicely with a lot of networking tasks. Plus there is no limit to the amount of data you can send via TCP. It is designed to be an open stream of data flowing in both/either direction. It is simply up to the application layer to determine what that data looks like.
Where do we fit in?
So... UDP and TCP... how do we use them? Is that what the CocoaAsyncSocket libraries provide? Implementations of TCP and UDP? Nope, not quite. As you can imagine, TCP and UDP are used all over the place. So naturally they are provided by the operating system. If you open up your terminal and type "man socket" you can see the low level BSD socket API. The libraries are essentially wrappers that sits on top of low-level socket API's and provide you, the developer, an easy to use framework in Objective-C.
So CocoaAsyncSocket provides a great API that simplifies networking for you. But networking can still be tricky, so we recommend you read the following before you get started: