- Introduction of TCP
- TCP format (Segment)
- Difference between URG and PUSH
- TCP three handshakes four waves
- Three-way handshake
- Four times to wave
- TCP format (Segment)
- TCP implementation of Node.js
- Basic introduction
- TCP is a long socket.
- Precautions for long connection
- Set the timeout
- Close the socket
- Method 1: Manually shut down the client
- Method two :socket.end(), the server tells the client to close the connection
- Control connection number
- maxConnections
- getConnections
- Shut down the server
- server.close()
- server.unref()
- A socket is a duplex flow
- Introduction to duplex flow
- Read about
- Read about
- About the pipe
- Other property methods of the socket
- socket.bufferSize
- Solution The port is occupied
pre-notify
References and photo sources
- In-depth understanding of the TCP/IP model
- TCP waved four times
- Maybe this will help you understand the OSI seven-layer model
- Difference between URG and PSH in TCP packet segments
Maintain ing…
Introduction of TCP
TCP format (Segment)
- Source port number (16 bits) n/A N/A Destination port number (16 bits) 0 to 65535 The computer identifies which service to access by using the port number, such as HTTP or FTP
- TCP is marked by reading packets with serial numbers. Assume that the current serial number is S and the length of the sent data is I, then the serial number of the next data is S + I. When establishing a connection, the computer usually generates a random number as the initial serial number value.
- 32 bit acknowledge answer number A signal that responds to data received by the receiver and is equal to the serial number of the data to be received next time. If the serial number of the sender is S and the length of the data sent is I, the acknowledgement number returned by the receiver is also S + I. When the sender receives this acknowledgement, it can be assumed that all previous data at this location has been received normally.
-
4-bit header Length Indicates the length of the TCP header, in 4 bytes. If there is no optional field, the value here is 5 (in 4 bytes), indicating that the LENGTH of the TCP header is 20 bytes. 1 represents 4 bytes, 4 bits and 8 states can represent 32 bytes.
-
Six reserved bits
-
Six-bit control bits TCP connections, transmissions, and disconnections are directed by these six control bits
- URG This package contains emergency data, which is read before others
- ACK(Acknowlegement) 1 indicates the confirmation number
- The PSH(push bit) cache will be full (manually set to 1), and data will be transferred immediately.
- RST(reset) Indicates that the connection segment needs to be reconnected
- SYN(synchronous) The SERIAL number bit indicates the connection to be established. When establishing a TCP connection, set this value to 1
- The FIN sender completes the bit. The FIN sender sets the FIN value to 1, indicating that the connection is to be disconnected
-
The 16-bit window value client and server communicate how much data to send each time
- 16-bit TCP checksum Whether the checksum data is complete The calculation of the TCP checksum includes the TCP header, data, and other padding bytes.
- The 16-bit emergency pointer indicates the location of the data marked URG in the TCP data section.
- optional
- data
Difference between URG and PUSH
The following reference is made to the difference between URG and PSH in TCP packet segments
Emergency URG (urgent) :
When URG = 1, it indicates that the urgent pointer field is valid, and it tells the system that there is urgent data in this message segment and it should be transmitted as soon as possible, instead of the original queuing order. The TCP of the sender puts the urgent data in the first part of the data in this message segment. The URG flag bit is used in conjunction with the emergency pointer field in the header, which points to a byte in the data segment (data from the first byte to the byte indicated by the pointer is emergency data). Note that emergency data can be sent even when the window is 0. Emergency data is not sent into the receive buffer and is directly handed to the upper process.
Push the PSH model (push) :
When two application processes communicate interactively, sometimes a client sends a request to the server and expects an immediate response. In this case, the client application notifies TCP to use a push operation. TCP sets PSH to 1 and immediately creates a message segment to send. TCP on a similar server receives a packet segment with the PSH flag and immediately delivers all received data to the server process as soon as possible, rather than waiting for the entire cache to fill up and deliver it up.
TCP three handshakes four waves
Three-way handshake
Q: Why do you shake hands? And three times?
A: The reason for shaking hands is to make sure that data is received and sent properly to each other (client, server) before actually sending data. The reason for shaking hands is three times, um… Please read on
Now let’s look at the detailed process
Note: the 1-bit signal in [] followed by = is the 16-bit serial number and confirmation number, which is the specific number.
01: Client [SYN]seq=0– > server
* * * * * * * * * * * * * * * * * *
02: client <– [SYN, ACK] SEq =0, ACK =1 Server
* * * * * * * * * * * * * * * * * *
03: Client [ACK]seq=1, ACK =1– > server
For the first handshake, the server receives a synchronization request from the client, and the server knows that the client is sending normally. (Hey, I I love you)
On the second handshake, the client receives an acknowledgement and synchronization message from the server, and the client knows that the server is sending and receiving (both) normally. (I also like you, let’s get married)
On the third handshake, the server receives the confirmation message from the client, and the server knows that the client receives the confirmation message properly. (Well, we get married)
This ensures that messages sent and received by each other are normal.
Four times to wave
Q: Why do you wave? And four times? A: The wave is meant to be an amicable parting, um… Signal to the other person that if there is anything left undone, do it quickly and get it over with. As for why four times, um.. Same old tricks, see the details
First of all, unlike synchronization, either side can break up
01: Side A [FIN,ACK]seq= XXX,ACK = YYY –> side B
* * * * * * * * * * * * * * * * * *
02: A square <– [ACK]seq=yyy, ACK = XXX +1 B square
* * * * * * * * * * * * * * * * * *
A <– [FIN,ACK]seq=yyy, ACK = XXX +1 B
* * * * * * * * * * * * * * * * * *
[ACK]seq= XXX +1, ACK = YYy +1– > B
Note: if party B receives the FIN from Party A and happens to have no data to send to Party A, then 02 and 03 will be merged into one
On the first wave, team A says they have nothing to send to team B, I’m going to disconnect, right
With the second wave, side B indicates that I know that you (Side A) are about to disconnect. Hold on while I send the rest of the data
Third wave, side B says I have no more data to send, you can disconnect
For the fourth wave, party A means that I have received the data you sent at last and I have really disconnected. This is my last word. At this time, party B will close its side if it receives it
For the fourth wave, party A will wait for 2MSL (4min) after the wave. If the FIN sent by Party B is received during this period, it means that the ACK sent by party B for the last wave is not received, and it will resend and refresh the waiting time. Party A is completely disconnected until it no longer receives FIN from party B within 2MSL (indicating that party B has received the last ACK and is closed).
TCP implementation of Node.js
Basic introduction
The TCP connection is implemented in Node.js using the built-in NET module
let net = require('net');
let server = net.createServer(function(socket){
...
}).lieten(8080);
Copy the code
The socket is commonly known as a socket. Why is it called a socket?
We can read the input of the client and write data to the client through socket.
Note: The default backlog is 511 server.listen(handle[, backlog][, callback])
TCP is a long connection
Precautions for long connection
Note that the socket is a long connection, which means it will remain connected until the client or server manually closes the connection.
And because it’s a long connection, the callback registered in createServer will only be executed once, even if you send messages to the server over a TCP connection every once in a while. (Unlike HTTP, where a request is executed once), we also typically pack a layer of on(‘data’) in createServer to monitor client input in real time for response.
net.createServer(function(socket){
socket.on('data'.function(buffer){ console.log(socket._readableState.length); })});Copy the code
Set the timeout
Because TCP connection is not like HTTP connection will automatically interrupt, So there may be a socket is not used for a long time but occupy the position of the situation, generally this time we will specify a timeout time to do some operations, such as asking whether the servant is in ah (anti-hang up), whether to shuttdown ah what.
socket.setTimeout(5000);
socket.on('timeout'.function(){
socket.write('Hello, is anyone there? ');
});
Copy the code
Closing the socket
Method 1: Manually shut down the client
Method two: socket.end(), the server tells the client to close the connection
This is equivalent to four waves of the server breaking up with the client.
After receiving the packet, the client will combine the second and third wave together, reply to the server with [FIN,ACK]seq= YYy,ACK = XXX +1, and trigger the registration event of socket.on(‘end’).
[warning] Unlike WS. End, it has a last word that closes the socket.
Control connection number
maxConnections
Set the maximum number of links for a server
server.maxConnections = 111;
Copy the code
getConnections
server.getConnections(function(err,count){//count is the number of current connections console.log(' The number of current connections${count}People, maximum capacity${server.maxConnections}`)})Copy the code
Shut down the server
server.close()
When server.close() is called, the server does not immediately close all connections. Close simply means that the server does not accept new requests and the current socket will continue to be used. The server is shut down and the close event is triggered when all the sockets are closed.
server.unref()
By calling the server.unref() method, you can make the server shut down automatically when all connections to the server are closed. The difference between this method and server.close is that unref does not prevent new sockets from garrisoning.
A socket is a duplex flow
Introduction to duplex flow
Sockets inherit from Duplex, which is a readable and writable stream
Duplex so long
let {Duplex} = require('stream');
let d = Duplex({
read(){
this.push('hello'); // Do not stop will always be'hello'Read this.push(null) as a read value; // stop reading},write(chunk,encoding,callback){console.log(chunk); callback(); //clearBuffer } })Copy the code
So, the socket can read and write using all writable and readable stream methods.
Read about
Sending data from the client to the server looks like writing, but the socket looks like reading. (similar to process.stdin.pipe(transform1).pipe(transform2), where stdin is also read)
We can read client input by listening for the on(‘data’) event.
socket.on('data'.function() {});Copy the code
You can also pause a readable stream using socket.pause, or continue reading through socket.resume.
About writing
The writable flow level of a socket is the same as that of a normal writable flow. The writable flow level of a socket is the same as that of a normal writable flow. The writable flow level of a socket is the same as that of a normal writable flow.
Socket end(‘something’) will have no output if you end the socket.
About the pipe
let ws = fs.createWriteStream(path.join(__dirname,'./1.txt'));
let server = net.createServer(function(socket){
socket.pipe(ws,{end:false}); // The second argument keeps the file from closing automaticallysetTimeout(function(){ ws.end(); // Close writable stream socket.unpipe(ws); // Cancel pipe},15000); });Copy the code
Other property methods of the socket
socket.bufferSize
Real-time buffer size for write()
Solution The port is occupied
let port = 8080;
server.listen(port,'localhost'.function(){
console.log(`server is running at ${port}`);
})
server.on('error'.function(err){
if(err.code === 'EADDRINUSE'){ server.listen(++port); }});Copy the code
Server and client
Creating a Server
let net = require('net');
let server = net.createServer(function(socket){
socket.setEncoding('utf8');
socket.on('data'.function(data){ console.log(data); / / read}) socket. Write ('ok'); / / write socket. The end (); // close socket}); server.on('connection'.function(){// Note that this event is similar to the getConnections event, but getConnections has err and count parameters console.log().'Client link');
})
server.listen(8080);
Copy the code
Creating a Server
- Net.createconnection (port[, host][, connectListener]) The default host is localhost
- Net.connect (port[, host][, connectListener]) is the first alias form
Unlike when the TCP server is created and the socket is used as an argument in the callback function, when the client is created, the return value of the createConnection is a socket
let net = require('net'); // port Which port to connect to hostlet socket = net.createConnection(8080,function(){
socket.write('hello'); Check / / write socket.'data'.function(data){ console.log(data); / / read}); });Copy the code