Technology Sharing

Network Programming: Basic Concepts

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. OSI Model

OSI model ===》Open System Interconnection Model ==》is divided into 7 layers:
Ideal model ==》Not yet realized
        tftp 
        b  /etc/passwd 
        a /etc/123
Application Layer
Presentation layer encryption and decryption gzip
Session layer Network disconnection, connection status, keep-close keep-alive

Transport layer TCP UDP protocol file video, audio
Network layer IP NAT

Link layer Switch Data formatting Frame check
Physical layer 100Mb/8 Gbits 100MB Coaxial cable 10Gb 2.4G 5G

From the bottom up, the most basic

2. TCP/IP Model

TCP/IP model ==》Internet model ==》is divided into 4 layers:
Practical Model ===》Industrial Standard
TCP/IP protocol stack
Application layer ====》Application
Transport layer ====》Port number tcp udp (which method to use for transmission,TCP is reliableUDP has high real-time performance
Network layer ====》IP address (How to find each other and host
Interface layer ====》Network card driver 1GB
pcap ,,,

3. TCP/IP protocol suite

    www.taobao.com ---> 192.168.0.19
    www.voa.com vpn  
DNS domain name resolution (usually in provinces)


DHCP (Dynamic Host Configuration Protocol)
Application layer:HTTP (Webpage) TFTP (Trivial File Transfer Protocol)FTP (Internet remote transmission)
                   SNMP (management and monitoring of network devices, systems, and applications) DNS ...
Transport layer: TCP UDP 56k modem
Network layer: IP ICMP (ping) RIP OSPF IGMP ...
Interface layer: ARP (Address Resolution Protocol) RARP ... ip--->mac
    arp,,,,
    192.160.0.112 


1. Network Basics

Network Basics ===》ABCDE Class
010  3333344444
IP address == network bits + host bits

IP address classification: dotted decimal ipv4 712934
    Category A: Ultra-large-scale network
                          8    8     8    8
        1.0.0.0 - 126.255.255.255  126.1.1.1 
        Network Number                                126.1.1.2
       255.0.0.0 (subnet mask)  
private:
        10.0.0.0 - 10.255.255.255
        127.0.0.1
    Category B: Medium to large scale networks
        128.0.0.0 - 191.255.255.255
        128.2.1.2  128.2.7.2
        255.255.0.0
private:
        172.16.0.0 - 172.31.255.255

   Category C: Small and medium-sized networks
       192.0.0.0 - 223.255.255.255
        255.255.255.0
private:
       192.168.0.0 - 192.168.255.255
Static Routing
        192.168.0.0
        192.168.0.1 Gateway
        192.168.0.255 (broadcast, all people in the LAN can receive it)

   Category D: Multicast andbroadcast
        224.0.0.0 - 239.255.255.255 (for group chats, not for everyone, not limited to LAN)
        192.168.0.255 == 255.255.255.255 (only in LAN, one person sends, everyone receives)
        235.1.2.3
        192.168.1.0 
192.168.0.1 Gateway
192.168.1.255 Broadcast

Category E: Experimental
        240.0.0.0 - 255.255.255.255
        
Class C Network:
The first three groups of the IP address are the network address, and the fourth group is the host address.
The highest binary digit must start with: 110xxxxx
Decimal range: 192.0.0.0 -223.255.255.255
Default network mask: 255.255.255.0
Number of networks: 2^24, approximately 2.09 million
Number of hosts: 2^8 254 + 2 ===》1 is the gateway 1 is the broadcast
Private address: 192.168.xx LAN address.
  
  sudo vim /etc/network/interfaces "Configure network"
  sudo /etc/init.d/networking restart      
  sudo reboot
    192.168.0.0
    192.168.0.1  route 
    192.168.0.255 boardcast
    801.n.g 
Configuration for single-machine Internet access:
1. There is a network interface and the network cable is inserted.
2. Have an IP address
3. Configure network settings
           ip (modify temporary ip): ifconfig ethX XXXX/24 up ifconfig ens33 192.168.0.13/24 (subnet mask) up  255.255.255.0
Gateway: route add default gw xxxx
            DNS:  vi /etc/resolv.conf  ==>nameserver 8.8.8.8
            Test: ping www.baidu.com
            netstat -anp (can view the network status of the computer)

2. Network Interface

1. socketFile descriptors - associated network devices) ==》BSD socket ==》A set of interface functions for network communication。socket api  application interface function interface
        2. ip+port address+port===》Address is usedIdentify the host
Ports usedIdentify the application

          Port is divided into TCP port / UDP port range: 1-65535
It is agreed that ports within 1000 are used by the system.
            http 80   www.baidu.com
                3306
                telnet 21 
                ssh 22

3. Network Byte Order

        Big-endian storage (low in high memory - network devices)
     Little endian 0x12345678 (low bits in low memory - host)
        12 00   
        00 12
        192.168.0.12 (big endian) "the most significant bit is stored first"
       12.0.168.192 (little endian)

4. UDP (User Datagram)

1. Features: No link, Unreliable, Big data

2. Framework: C/S model

   server:socket() ===>bind()===>recvfrom()===>close()
   client:socket() ===>bind()===>sendto() ===>close()

Note: The parameters of socket() need to be adjusted.

      socket(PF_INET,SOCK_DGRAM,0);

      bind() client (c) is optionalServer(s) is required

1.socket 

int socket(int domain, int type, int protocol);
Function: The program proposes to the kernelCreate a memory-based socket descriptor

parameter:domain address family, PF_INET == AF_INET ==> Internet program
PF_UNIX == AF_UNIX ==> Standalone program

          type socket type:
SOCK_STREAM stream socket ===》TCP
SOCK_DGRAM User datagram socket ===> UDP
SOCK_RAW raw socket ===》IP

          protocol protocol ==》0 means automatic adaptation to the application layer protocol.

Return value: Successful returnRequested socket id
Failure -1;

 2.bind

        int bind(int sockfd, struct sockaddr *my_addrsocklen_t addrlen);
Function: If the function isService-TerminalCalling means associating the file descriptor file related to parameter 1 with the interface address specified by parameter 2.Receive data from this interface

If the function is inClient callIf it is used, it means that the data is taken from the descriptor where parameter 1 is located and from the interface device where parameter 2 is located. Send it out

Note: If it is a client, this function can be omitted and the data will be sent by the default interface.
parameter:sockfd file descriptor previously created by the socket function, socket id
          my_addr is a pointer to the structure of the physical interface. It indicates the information of the interface

struct sockaddr general address structure
      {
u_short sa_family; address family
char sa_data[14]; address information
      };

The converted network address structure is as follows:
struct _sockaddr_in ///Network address structure
      {
u_short sin_family; address family
u_short sin_port; ///Address port
struct in_addr sin_addr; ///Address IP
char sin_zero[8]; placeholder
      };

      struct in_addr
      {
          in_addr_t s_addr;
      }

socklen_t addrlen: length of parameter 2.
Return value: Success 0
Failure -1;

3. Sendtake overfunction:

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                       
const struct sockaddr *dest_addr, socklen_t addrlen);

Function: Used in UDP protocol to send data to the other partysend data
parameter:sockfd local socket id
           buff local data storage, usually the data to be sent
          len The length of the data to be sent
          flags The way to send data.0 means blocking sending

          dest_addr: required, indicating the target host information structure to be sent to
        addrlen: target address length

Return value: Success Length of data sent
Failure -1;


ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                          
struct sockaddr *src_addr, socklen_t *addrlen);

Function: used in UDP protocolObtainData sent by the other party.
parameter:sockfd local socket id
          buff is the memory area where data is stored, usually an array or dynamic memory
        len is the length of the data to be obtained, usually the size of buff
           How to obtain flags,0 Blocked

          src_addr is optional and indicates the address information structure of the other party.NULL,expressDon't care about the other party's address
          addrlen The size of the other party's address information structure. IfThe other party's addressyesNULL, thenThis value is also NULL
Return value: length of data successfully received
Failure -1;

4. Close

close() ===>Close the specified socket id;


Notice

1. Data has boundaries
2. The number of sending and receiving times must correspond
3. recvfrom will block
4. sento will not block (recvfrom does not receive, does not affect sento sending) 


   c find s

server.c 

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <time.h>
  10. typedef struct sockaddr *SA;
  11. int main(int argc, char *argv[])
  12. {
  13. int sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 创建一个UDP套接字
  14. if(-1 == sockfd) // 检查socket调用是否失败
  15. {
  16. perror("socket"); // 打印错误信息
  17. exit(1); // 退出程序
  18. }
  19. // 定义服务器地址和客户端地址结构体(尽管客户端地址通常在recvfrom中填充)
  20. struct sockaddr_in ser, cli;
  21. bzero(&ser, sizeof(ser)); // 初始化服务器地址结构体
  22. bzero(&cli, sizeof(cli)); // 初始化客户端地址结构体(但这里实际上不需要提前初始化)
  23. // 设置服务器地址结构体
  24. ser.sin_family = AF_INET;
  25. ser.sin_port = htons(50000); // 端口号转换为网络字节序
  26. ser.sin_addr.s_addr = inet_addr("192.168.203.128"); // 服务器IP地址
  27. // 将套接字绑定到服务器地址和端口
  28. int ret = bind(sockfd, (SA)&ser, sizeof(ser));
  29. if(-1 == ret)
  30. {
  31. perror("bind"); // 绑定失败时打印错误信息
  32. exit(1); // 退出程序
  33. }
  34. socklen_t len = sizeof(cli); // 用于recvfrom的客户端地址长度
  35. // 无限循环接收数据并发送响应
  36. while(1)
  37. {
  38. char buf[512] = {0}; // 准备接收数据的缓冲区
  39. // 接收数据,注意这里&len是必需的,因为recvfrom会修改它以反映实际接收到的客户端地址长度
  40. recvfrom(sockfd, buf, sizeof(buf), 0, (SA)&cli, &len);
  41. time_t tm;
  42. time(&tm); // 获取当前时间
  43. // 这里有一个问题:buf被用于接收数据,然后又被用于存储新的字符串(包括原始数据和时间戳)
  44. // 这会导致原始数据被覆盖。应该使用另一个缓冲区来存储最终的发送数据
  45. sprintf(buf, "%s %s", buf, ctime(&tm)); // 将时间戳附加到接收到的数据上
  46. // 发送数据回客户端,但注意len在这里已经被recvfrom修改,表示客户端地址的长度
  47. // 对于sendto,我们应该使用sizeof(cli)或重新初始化len
  48. sendto(sockfd, buf, strlen(buf), 0, (SA)&cli, len); // 这里使用len可能不是最佳实践
  49. }
  50. // 注意:由于程序进入了一个无限循环,下面的close和return语句实际上永远不会被执行
  51. close(sockfd); // 正常情况下应该关闭套接字
  52. return 0; // 程序正常结束
  53. }

client.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <sys/types.h> /* See NOTES */
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <netinet/ip.h>
  9. #include <arpa/inet.h>
  10. #include <time.h>
  11. // 定义一个类型别名SA,指向sockaddr结构体
  12. typedef struct sockaddr *SA;
  13. // 注意:它尝试定义一个函数指针类型而不是简单的结构体指针。
  14. int main(int argc, char *argv[])
  15. {
  16. // 创建一个UDP套接字
  17. int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  18. if(-1 == sockfd)
  19. {
  20. perror("socket"); // 如果创建套接字失败,打印错误信息
  21. exit(1); // 退出程序
  22. }
  23. // 初始化sockaddr_in结构体,用于指定服务器地址和端口
  24. struct sockaddr_in ser;
  25. bzero(&ser, sizeof(ser)); // 将结构体内存清零
  26. ser.sin_family = AF_INET; // 使用IPv4地址
  27. // 将端口号从主机字节序转换为网络字节序
  28. ser.sin_port = htons(50000);
  29. // 将点分十进制的IP地址字符串转换为网络字节序的整数
  30. ser.sin_addr.s_addr = inet_addr("192.168.203.128");
  31. // 无限循环,发送数据并尝试接收响应
  32. while(1)
  33. {
  34. char buf[512] = "hello,this is udp test"; // 准备发送的数据
  35. // 发送数据到指定的服务器地址和端口
  36. sendto(sockfd, buf, strlen(buf), 0, (SA)&ser, sizeof(ser));
  37. // 清空缓冲区,准备接收数据
  38. bzero(buf, sizeof(buf));
  39. // 尝试接收数据,但源地址和端口被设置为NULL,这通常是不正确的
  40. // 在实际应用中,应该提供一个sockaddr_in结构体来接收源地址和端口信息
  41. recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);
  42. // 打印接收到的数据(但在这个例子中,由于recvfrom的源地址和端口被设置为NULL,它可能不会按预期工作)
  43. printf("buf is %sn", buf);
  44. // 等待1秒后再发送下一个数据包
  45. sleep(1);
  46. }
  47. // 注意:由于程序进入了一个无限循环,下面的close和return语句实际上永远不会被执行
  48. close(sockfd); // 关闭套接字
  49. return 0; // 程序正常结束
  50. }