linux network programming
1, Understanding of ip and ports
- What is socket?
1). Socket is translated into socket, socket and row plug in English. (because there are many kinds of sockets, it seems that there are many protocols. These protocols must be consistent before communication can be carried out.)
Network programming - > socket programming, socket programming.
2). socket() is also a function interface.
The function function is to create a socket.
3). Socket also refers to socket word - > special file descriptor.
-
What is an IP address?
For example: 192.168.14.2 - > point by point system
In a local area network, each host will have an IP address, and the IP address must be the same network segment - > it refers to that the first three digits of the IP address are the same.
Each IP address is 32 bits. If the IP address is used in the network programming code, the 32-bit data must be converted into network bytes.
(in short: the communication between computers requires an address. With an address, I can accurately communicate with Xiaoming's computer, which is equivalent to the house number in daily life. With a house number, I can find Xiaoming's home. If there is no IP address / house number, how can I communicate with Xiaoming's computer / find Xiaoming's home?) -
What is a port number?
In a LAN, two hosts need to communicate. In addition to the IP address in the same network segment, they also need to use the same port number.
(in fact, the port number is like QQ on the computer. The port number is actually the address of the application on the computer, because it is not enough for us to identify and find the corresponding computer host through the IP address, but also to find the corresponding application. The communication between QQ is actually the same port number, so why can't QQ communicate with wechat? Obviously, the port number is different)host A host B
Network segment with the same IP address: 192.168.14.2 192.168.14.4
Same port number: 5000
The port number is 16 bits. If the port number is used in the code of network programming, the 16 bit data must be converted into network bytes.
Ports used by the system: 0 ~ 1023 (users cannot use)
User's valid port: 1024 ~ 65535 (user's free use) - > after using the port number, wait at least 1 minute before using it again.
- How to view and configure the IP address of ubuntu
Check other information by yourself. There's no need to say more here.
2, Communication protocol ---- TCP
-
TCP protocol features?
Full name of TCP protocol: Tranmission Control Protocol
Transmission control protocolTCP protocol communication is similar to making a phone call in reality. You must connect to communicate. - > TCP protocol is a reliable transmission mode.
TCP protocol action scenario: account login and file transfer. -
Analyze the principle of TCP protocol.
TCP protocol can connect normally because both parties follow the three-time handshake protocol.
1) First handshake:
When establishing a TCP connection, the client sends a syn packet (seq=j) to the server, and the client waits for the server to confirm.2) Second handshake:
After receiving the syn packet, the server must confirm the SYN(ack=j+1) of the client. At the same time, the server will also send a syn packet (seq=k) to the client, that is, SYN+ACK. At this time, the server enters the waiting state.3) Third Handshake:
The client receives the SYN+ACK packet sent by the server and wants the server to send a confirmation packet (ACK=k+1). After the packet is sent, the client and the server are connected. -
1). Create TCP socket
Interface declaration: int socket(int domain, int type, int protocol);Parameters:
Domain: domain.AF_INET/PF_INET: Internet Protocol AF_UNIX/PF_UNIX: Local agreement, which can be written as AF_LOCAL/PF_LOCAL
Type: type.
SOCK_STREAM: stream socket SOCK_DGRAM: Datagram Socket
Protocol: protocol.
Generally 0Return value:
Success: socket to be connected
Failed: - 1Note: in the internet protocol, selecting streaming socket represents TCP protocol, and selecting packet socket represents UDP protocol. The third parameter protocol is generally not used.
2) Bind IP address and port number
Interface declaration: int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);Parameters:
sockfd: socket to be connected
addr: pointer to the universal address structure containing the local address (IP+PORT)
addrlen: address structure sizeReturn value:
Success: 0
Failed: - 1remarks:
Definition of general address structure:
struct sockaddr { sa_family_t sa_family; -> agreement -> 2 char sa_data[14]; -> IP,Port number.. };
Special address structure - IPv4 address structure:
struct sockaddr_in { u_short sin_family; // Address family - > 2 u_short sin_port; // Port number - > 2 struct in_addr sin_addr; // IPV4 address - > 4 char sin_zero[8]; }; struct in_addr { in_addr_t s_addr; // Unsigned 32-bit network address - > IP };
3) Set listening socket
Interface declaration: int listen(int sockfd, int backlog);
Parameters:
sockfd: socket to be connected
backlog: maximum number of connection requests received simultaneously
Return value:
Success: 0, and set sockfd to listen socket
Failed: - 1
4) Waiting for peer connection request
Interface declaration: int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
Parameters:
sockfd: listening socket
addr: general address structure, which is used to store the peer address (IP+PORT)
addrlen: storage area size of parameter addr
Return value:
Success: connected socket (non negative integer)
Failed: - 1
5) Receive data from TCP socket
Interface declaration: ssize_t recv(int sockfd, void *buf, size_t len, int flags);
Parameters:
sockfd: connected socket
buf: store data buffer
len: buffer size
flags: receive flag, which can be set to 0.
Return value:
Success: bytes received
Failed: - 1
6) Convert text address to binary address
Interface declaration: int inet_pton(int af, const char *src, void *dst);
Parameters:
af: address family. AF_INET: IPv4 address
src: pointer to "dotted" IPv4 or IPv6 address, such as "192.168.1.100"
dst: type struct in_ Pointer to addr *
Return value:
Success: 1
Failure: 0 means the address does not match the address family, - 1 means the address is illegal
7) Convert binary address to text address
Interface declaration: const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
Parameters:
af: address family.
AF_INET: IPv4 address AF_INET6: IPv6 address
src: type struct in_addr * or struct in6_ Pointer to addr *
dst: address buffer pointer, buffer at least
Size: address buffer size, at least INET_ADDRSTRLEN or INET6_ADDRSTRLEN bytes
Return value:
Success: dst
Failed: NULL
8) Connect peer listening socket
Interface declaration: int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
Parameters:
sockfd: socket to be connected
addr: pointer to the general address structure containing the opposite end address (IP+PORT)
addrlen: address structure size
Return value:
Success: 0
Failed: - 1
-Simply, we can understand the above content by analyzing two pieces of code
Server side (rose):
Compile:/ rose 50000
rose is the file name and 50000 is the port number
#include "head.h" int main(int argc,char *argv[]) // ./rose 50000 { //1. Create TCP socket int sockfd; sockfd = socket(AF_INET,SOCK_STREAM,0);//AF_INET: Internet Protocol SOCK_STREAM: socket stream printf("sockfd = %d\n",sockfd); //2. Bind IP address and port number struct sockaddr_in srvaddr; socklen_t len = sizeof(srvaddr); bzero(&srvaddr,len); srvaddr.sin_family = AF_INET; //Address family, AF_INET: Internet Protocol (ipv4 address) srvaddr.sin_port = htons(atoi(argv[1])); //Port number htons: converts an unsigned short integer value to network byte order atoi: converts a string to an integer number srvaddr.sin_addr.s_addr = htonl(INADDR_ANY); //IP address / usr / include / Linux / in H / / htonl: convert the unsigned long integer number of the host to the network byte order //INADDR_ANY: refers to the current IP address of the server bind(sockfd,(struct sockaddr *)&srvaddr,len); //Bind IP + port //3. Set listening socket //Before calling listen: sockfd - > socket to be connected listen(sockfd,5); //After calling listen: sockfd - > Listen socket //4. Wait for the client to connect struct sockaddr_in cliaddr; int connfd; connfd = accept(sockfd,(struct sockaddr *)&cliaddr,&len);//Blocking waits for the client to establish a connection. If successful, a socket file descriptor successfully connected with the client is returned if(connfd >= 0) { printf("connfd = %d\n",connfd); printf("new connection:%s\n",inet_ntoa(cliaddr.sin_addr)); } //5. Read data on socket char buf[100]; while(1) { bzero(buf,sizeof(buf)); //block recv(connfd,buf,sizeof(buf),0);//It is used to receive the data sent by the remote host through socket sockfd and save these data into the array buf. printf("from jack:%s",buf); if(strncmp(buf,"fenshou",7) == 0) { break; } } //6. Reclaim TCP socket resources close(sockfd); close(connfd); return 0; }
Client (jack):
Compile:/ jack 192.168.14.11 50000
jack: the program file name
192.168.14.11: IP address of the server
50000: port number (must be the same as the port number of the server)
#include "head.h" int main(int argc,char *argv[]) // ./jack 192.168.14.11 50000 { //1. Create TCP socket int sockfd; sockfd = socket(AF_INET,SOCK_STREAM,0); printf("sockfd = %d\n",sockfd); //2. Prepare rose's IP address. struct sockaddr_in srvaddr; socklen_t len = sizeof(srvaddr); bzero(&srvaddr,len); srvaddr.sin_family = AF_INET; //Address family srvaddr.sin_port = htons(atoi(argv[2])); //Port number inet_pton(AF_INET,argv[1],&srvaddr.sin_addr); //Set Rose's IP address //3. Initiate connection //Before the connect call: sockfd - > socket to be connected int ret = connect(sockfd,(struct sockaddr *)&srvaddr,len); if(ret == 0) { printf("connect success!\n"); } //After the connect call: sockfd - > connected socket //4. Send data to rose char buf[100]; while(1) { bzero(buf,sizeof(buf)); fgets(buf,sizeof(buf),stdin); //Get the data from the keyboard and put it into the buffer buf send(sockfd,buf,strlen(buf),0); //It is used to send the data in buf to another host //Parameter: 1 Socket: Specifies the sender socket descriptor. 2.buf: indicates the buffer for storing sent data. 3.strlen actual number of bytes to be sent, 4 The fourth parameter is generally set to zero //If you enter fenshou on the keyboard, you exit if(strncmp(buf,"fenshou",7) == 0) { break; } } //5. Reclaim TCP socket resources close(sockfd); return 0; } /*In main(int argc,char *argv []); argc Indicates the number of parameters during execution argv[]Represents one of the execution parameters Suppose a program is my When I execute. Exe, I/ my ss yy argc is 3, argv[0] is my,argv[1] is ss,argv[2] is yy Also in this code, argv[1] and argv[2] in line 16 and 17 refer to the comments in the third line This file executes/ jack 192.168.14.11 50000, so it's easy to get the principle of this generation of program from now on */
- Of course, the above code can only realize that the client sends data to the server one way
- To realize two-way data sending and receiving, a little bit of system programming > thread knowledge is involved. The following code is provided
Server side:
#include "head.h" void *func(void *arg) { int connfd = *(int *)arg; //Continuously receive data char buf[100]; while(1) { bzero(buf,sizeof(buf)); recv(connfd,buf,sizeof(buf),0); printf("from client:%s",buf); if(strncmp(buf,"quit",4) == 0) { exit(0); } } } int main(int argc,char *argv[]) // ./server 50001 { //1. Create TCP socket int sockfd; sockfd = socket(AF_INET,SOCK_STREAM,0); //2. Bind IP address to socket struct sockaddr_in srvaddr; socklen_t len = sizeof(srvaddr); bzero(&srvaddr,len); srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(atoi(argv[1])); srvaddr.sin_addr.s_addr = htonl(INADDR_ANY); bind(sockfd,(struct sockaddr *)&srvaddr,len); //3. Set listening socket listen(sockfd,5); //4. Keep waiting for the other party's connection struct sockaddr_in cliaddr; int connfd; connfd = accept(sockfd,(struct sockaddr *)&cliaddr,&len); if(connfd > 0) { printf("new connection:%s\n",inet_ntoa(cliaddr.sin_addr)); } //5. Create sub thread pthread_t tid; pthread_create(&tid,NULL,func,(void *)&connfd); //6. Continuously send data to the client char buf[100]; while(1) { bzero(buf,sizeof(buf)); fgets(buf,sizeof(buf),stdin); send(connfd,buf,strlen(buf),0); if(strncmp(buf,"quit",4) == 0) { break; } } close(sockfd); close(connfd); return 0; }
client:
#include "head.h" void *func(void *arg) { int sockfd = *(int *)arg; char buf[100]; while(1) { bzero(buf,sizeof(buf)); recv(sockfd,buf,sizeof(buf),0); printf("from server:%s",buf); if(strncmp(buf,"quit",4) == 0) { exit(0); } } } int main(int argc,char *argv[]) // ./jack 192.168.14.4 50000 { //1. Create TCP socket int sockfd; sockfd = socket(AF_INET,SOCK_STREAM,0); printf("sockfd = %d\n",sockfd); //2. Prepare rose's IP address. struct sockaddr_in srvaddr; socklen_t len = sizeof(srvaddr); bzero(&srvaddr,len); srvaddr.sin_family = AF_INET; //Address family srvaddr.sin_port = htons(atoi(argv[2])); //Port number inet_pton(AF_INET,argv[1],&srvaddr.sin_addr); //Set Rose's IP address //3. Initiate connection //Before the connect call: sockfd - > socket to be connected int ret = connect(sockfd,(struct sockaddr *)&srvaddr,len); if(ret == 0) { printf("connect success!\n"); } //After the connect call: sockfd - > connected socket //Create thread pthread_t tid; pthread_create(&tid,NULL,func,(void *)&sockfd); //4. Send data to rose char buf[100]; while(1) { bzero(buf,sizeof(buf)); fgets(buf,sizeof(buf),stdin); send(sockfd,buf,strlen(buf),0); if(strncmp(buf,"quit",4) == 0) { break; } } //5. Reclaim TCP socket resources close(sockfd); return 0; }
I Communication protocol. – UDP protocol
TCP -> Tranmission Control Protocol
UDP -> User Data Protocol
IP -> Internet Protocol
-
What is the difference between TCP protocol and UDP protocol?
TCP protocol is a reliable transmission method for connected situations. - > You must be connected to communicate.
UDP protocol is an unreliable transmission mode for connectionless situations. - > You can send data without a connection. -
How?
UDP protocol - > similar to writing letters.
2, Implementation process.
-
The server:
//1. Create UDP socket
int sockfd;
sockfd = socket(AF_INET,SOCK_DGRAM,0);//2. Binding.
bind(sockfd,(struct sockaddr *)&srvaddr,len);//3. Wait for the other party's data.
recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&cliaddr,&len);//4. close
close(sockfd); -
client:
//1. Create UDP socket
int sockfd;
sockfd = socket(AF_INET,SOCK_DGRAM,0);//2. Just send data directly.
sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&srvaddr,len);//3. close
close(sockfd); -
Two new things we need to know
-
Receive data from UDP socket
Interface declaration: ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);Parameters:
sockfd: UDP socket
buf: store data buffer
len: buffer size
Flags: receive flag, which is completely consistent with the flags of the function send
src_addr: peer network address
addrlen: address lengthReturn value:
Success: bytes received
Failed: - 1 -
Send data to UDP socket
Interface declaration: ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);Parameters:
sockfd: UDP socket
buf: data to be sent
len: length of data
Flags: send flag, which is completely consistent with the flags of the function send
dest_addr: peer network address
addr_len: address lengthReturn value:
Success: bytes sent
Failed: - 1
- The following is the code of UDP communication
Server side:
#include "head.h" int main(int argc,char *argv[]) //./rose 50002 { //1. Create UDP socket int sockfd; sockfd = socket(AF_INET,SOCK_DGRAM,0); //2. Bind IP address, port number and address family to UDP socket struct sockaddr_in srvaddr; socklen_t len = sizeof(srvaddr); bzero(&srvaddr,sizeof(srvaddr)); srvaddr.sin_family = AF_INET;//Address family srvaddr.sin_port = htons(atoi(argv[1]));//Port number srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);//IP address / usr / include / Linux / in h //Bind ip + port bind(sockfd,(struct sockaddr *)&srvaddr,len); //3. Keep waiting for the client to send data to itself char buf[100]; struct sockaddr_in cliaddr; while(1) { //Empty buffer bzero(buf,sizeof(buf)); //Waiting for the other party's data recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&cliaddr,&len); . printf("from jack:%s",buf); if(strncmp(buf,"quit",4) == 0) { break; } } //4. Recycling close(sockfd); return 0; }
client:
#include "head.h" int main(int argc,char *argv[]) //./rose 192.168.14.4 50002 { //1. Create UDP socket int sockfd; sockfd = socket(AF_INET,SOCK_DGRAM,0); //2 prepare rose's address. struct sockaddr_in srvaddr; socklen_t len = sizeof(srvaddr); bzero(&srvaddr,sizeof(srvaddr)); srvaddr.sin_family = AF_INET;//Address family srvaddr.sin_port = htons(atoi(argv[2]));//Port number inet_pton(AF_INET,argv[1],&srvaddr.sin_addr);//Set rose's address //3. Keep writing to rose. char buf[100]; while(1) { bzero(buf,sizeof(buf)); fgets(buf,sizeof(buf),stdin);//Enter data from the keyboard //Send data directly sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&srvaddr,len); if(strncmp(buf,"quit",4) == 0) { break; } } //4. Recycling resources close(sockfd); }
-
What is the IO model?
Network programming for data output and input methods: blocking IO, non blocking IO, multiplexing, signal driving. -
How do these IO models work?
1) Blocking IO: always blocking and waiting for the data of a socket to arrive. If there is data, it will be read and returned. If there is no data, it will always wait.
read(fd);
recv(fd);
accept(sockfd);
In the past, we all thought that the above examples were blocked by functions, such as read function and accept function, but it is wrong to think so, because the real blocking is the socket / file descriptor, not the function itself.Because fd is the file descriptor - > fd is the blocking attribute by default - > read (fd) - > blocking
2, Non blocking IO
-
If you want to use non blocking IO, what is the idea?
1) First create a file descriptor / socket - > blocking attribute by default.
2) Set the non blocking attribute to the file descriptor - > at this time, the file descriptor is non blocking.
3) When you call read()/accept()/recv() to process the file descriptor, it will be non blocking. -
How to set non blocking attribute to file descriptor? - > fcntl() -> man 2 fcntl
Header file:
#include <unistd.h>
#include <fcntl.h>Prototype:
int fcntl(int fd, int cmd, ... /* arg */ );Parameters:
fd: the file descriptor for which the attribute needs to be setcmd:
F_GETFL (void) -> void Represents the third parameter, which does not need to be filled in Get the file access mode and the file status flags; arg is ignored. //Gets the properties of the current file descriptor
F_SETFL (int) -> int It means that the following parameter needs to be filled in Set the file status flags to the value specified by arg. O_NONBLOCK -> Non blocking attribute
Return value:
success:
F_GETFL returns the properties of the file
F_SETFL returned 0
Failed: -1
- Let's understand it through a piece of code
Server side
#include "head.h" int main(int argc,char *argv[]) { //1. Create a TCP socket int sockfd; sockfd = socket(AF_INET,SOCK_STREAM,0); //2. Bind IP address and port number struct sockaddr_in srvaddr; socklen_t len = sizeof(srvaddr); bzero(&srvaddr,len); srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(atoi(argv[1])); srvaddr.sin_addr.s_addr = htonl(INADDR_ANY); bind(sockfd,(struct sockaddr *)&srvaddr,len); //3. Set listening socket listen(sockfd,5); //Sockfd - > blocking attribute by default //4. Add non blocking attribute to sockfd int state; state = fcntl(sockfd,F_GETFL); //state is the current property of sockfd. state |= O_NONBLOCK; //state is the new attribute fcntl(sockfd,F_SETFL,state); //Sockfd - > has non blocking attribute //5. Wait for the client to connect struct sockaddr_in cliaddr; bzero(&cliaddr,len); int connfd; while(1) { connfd = accept(sockfd,(struct sockaddr *)&cliaddr,&len); if(connfd > 0) //If someone connects, it will return success { printf("connfd = %d\n",connfd); printf("new connection:%s\n",inet_ntoa(cliaddr.sin_addr)); break; } else{ //If no one connects, failure will be returned printf("connect error!\n"); } } close(sockfd); close(connfd); return 0; }