Before we start learning network programming, let's first understand what TCP protocol is: TCP/IP(Transmission Control Protocol/Internet Protocol), which is a connection-oriented, reliable, byte-stream-based Transport layer communication protocol. It is divided into application layer, transmission layer, network layer and data link layer. What is the role of each layer?
Application Layer: Determining the Activities of Users Providing Application Service Communication
Transport Layer: Provides data transmission between two computers connected to the network (TCP/UDP)
Network Layer: Processing Packets Flowing over the Network
Link Layer: Processing the Hardware Part of the Connected Network
TCP's three handshakes: the sender first sends a packet with SYN flag to the other party, the receiver receives it, sends back a packet with SYN/AK flag to convey confirmation information, and finally, the sender sends back a packet with ACK flag.
DSN Protocol: Providing Resolution Service between Domain Name and IP Address
The difference between TCP and UDP:
- TCP is connection-oriented (e.g. dialing to establish a connection before making a call); UDP is connectionless, i.e. no connection is needed before sending data.
- TCP provides reliable services - no errors, no loss, no duplication; UDP does its best to deliver, that is, it does not guarantee reliable delivery.
- TCP is byte-oriented throttling (TCP regards data as a series of unstructured byte streams); UDP is message-oriented and has no congestion control.
- Each TCP connection can only be point-to-point; UDP is one-to-one, one-to-many, many-to-one and many-to-many interactive communications
- TCP header overhead is 20 bytes; UDP header overhead is small, only 8 bytes.
- The logical communication channel of TCP is full duplex reliable channel; UDP is unreliable channel.
Function of port number
Host Differential Services - IP Address + Port Number
Ports provide access channels, and servers are identified by well-known ports.
The TCP ports of FTP servers are 21; the TCP port number of Telnet servers is 23; and the UDP port number of each TFTP (Simple File Transfer Protocol) server is 69.
Byte order: The order in which multibyte data is stored in computer memory or transmitted over the network
Little endian small endian byte order
Big endian Big Endian Big End Byte Order
Network byte order = large-end byte order
Byte sequencing API - h stands for host, n for net, l for long (4 bytes), s for short (2 bytes)
#include <netinet/in.h> //Conversion between host byte order and network byte order uint16_t htons(uint16_t host16bitvalue); //Returns the value of the network byte order uint32_t htonl(uint32_t host32bitvalue); //Returns the value of the network byte order uint16_t ntohs(uint16_t net16bitvalue); //Returns the value of the host byte order uint32_t ntohl(uint32_t net32bitvalue); //Returns the value of the host byte order
Development steps of Sockt server and client
- Create sockets
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int socket(int domain, int type, int protocol);
- Add information for sockets (IP address and port number)
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
Function: Used to bind IP address and port number to socketfd
Description of parameters:
sockfd: socket descriptor
addr: A pointer to the sockaddr type containing information such as IP address and port number, and to the protocol address structure to be bound to sockfd
Address Transfer API
int inet_aton(const char* straddr,struct in_addr *addrp); //Convert the string form "192.168.1.123" to a network-recognizable format char* inet_ntoa(struct in_addr inaddr); //Converting ip addresses in network format to strings
- Monitoring Network Connection
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int listen(int sockfd, int backlog);
- Listen for client access, receive a connection
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
- Data Interaction
First set of API s
#include <unistd.h> ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count);
The second API
#include <sys/types.h> #include <sys/socket.h> int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);//Receiving by Client
6. Close socket and disconnect
Complete server and client development code:
server.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <unistd.h> int main(int argc, char **argv) { int s_fd; int c_fd; char readbuf[128]; int n_read; char mbuf[128] = {0}; // socket struct sockaddr_in s_addr; struct sockaddr_in c_addr; memset(&s_addr, 0, sizeof(struct sockaddr_in)); memset(&c_addr, 0, sizeof(struct sockaddr_in)); s_fd = socket(AF_INET, SOCK_STREAM, 0); if (argc != 3) { //Judging whether there are three parameters of a function printf("falut\n"); exit(-1); } if (s_fd == -1) { perror("socket"); exit(-1); } s_addr.sin_family = AF_INET; s_addr.sin_port = htons(atoi(argv[2]));//Converting port number to network byte order inet_aton(argv[1], &s_addr.sin_addr);//Address to API, String to Network Recognizable Address // bind bind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));//Add IP and port number information // listen listen(s_fd, 10);//Monitor // accept int clen = sizeof(struct sockaddr_in); while (1) { c_fd = accept(s_fd, (struct sockaddr *)&c_addr, &clen);//Receiving Client if (c_fd == -1) { perror("accept"); } printf("get connect:%s\n", inet_ntoa(c_addr.sin_addr)); printf("connect\n"); if (fork() == 0) { if (fork() == 0) {//Subprocess bytes are written to bytes while (1) { memset(mbuf, 0, sizeof(mbuf)); printf("input:"); gets(mbuf); write(c_fd, mbuf, strlen(mbuf)); } } while (1) { memset(readbuf, 0, sizeof(readbuf)); n_read = read(c_fd, readbuf, 128); //Read bytes if (n_read == -1) { printf("read"); } else { printf("\nget %d byte,message:%s\n", n_read, readbuf); } } break; } } return 0; }
client.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <unistd.h> int main(int argc, char **argv) { int c_fd; char readbuf[128]; int n_read; char mbuf[128] = {'\0'}; // socket struct sockaddr_in c_addr; memset(&c_addr, 0, sizeof(struct sockaddr_in)); c_fd = socket(AF_INET, SOCK_STREAM, 0); if (argc != 3) { printf("falut\n"); exit(-1); } if (c_fd == -1) { perror("socket"); exit(-1); } c_addr.sin_family = AF_INET; c_addr.sin_port = htons(atoi(argv[2])); inet_aton(argv[1], &c_addr.sin_addr); // connect if (connect(c_fd, (struct sockaddr *)&c_addr, sizeof(struct sockaddr)) == -1) { //Connecting servers perror("connect"); exit(-1); } while (1) { if (fork() == 0) { while (1) { memset(mbuf, 0, sizeof(mbuf)); printf("input :"); gets(mbuf); write(c_fd, mbuf, strlen(mbuf)); } } while (1) { memset(readbuf, 0, sizeof(readbuf)); n_read = read(c_fd, readbuf, 128); if (n_read == -1) { perror("read"); } else { printf("\nget %d byte,message from server:%s\n", n_read, readbuf); } } } return 0; }
Function: