Question: What is the meaning of some parameters in the network programming interface?
sock = socket(PF_INET, SOCK_STREAM, 0);
Detailed explanation of socket parameters
int socket(int domain, int type, int protocal);
parameter | significance |
domain | Protocol family information used in sockets |
type | Socket data transfer type information |
prorocol | Protocol information used for communication between devices |
domain parameter (protocol family) in socket()
- PF_INET → IPv4 Internet Protocol Suite
- PF_INET6 → IPv6 Internet Protocol Suite
- PF_LOCAL → protocol family for local communication
- PF_PACKET → low-level data transceiver protocol
- PF_IPX → Novell Proprietary Protocol (Internet Packet Exchange Protocol)
- ...
注意:不同协议中的地址表现形式可能不同,网络编程时地址类型必须和协议类型匹配
type and protocol parameters in socket()
type : used to specify the protocol type
- SOCK_STREAM : streaming data (TCP)
- SOCK_UGRAM : Packet data (UDP)
protocol : used to specify the specific protocol that the protocol family conforms to the type
- Domain and type can almost uniquely determine a protocol, so this parameter is usually 0
- That is: 0 represents the default protocol after domain and type are specified
About port numbers and IP addresses
- The port number is a 2-byte data (unsigned)
- 0 - 1024 are predefined as a specific port (assigned to a specific application)
- IP address is a 4-byte unsigned address family (can be divided into 5 types of addresses)
Deep dive into IP addresses
IP address is divided into two parts: network ID and host ID
- Network ID: Identifies the network where the network host (device) is located
- Host ID: Identify the specific address of the network host (device)
Question: An IP address is only 4 bytes, so how to distinguish the network ID from the host ID?
- IP Address and Subnet Mask Use Together to Distinguish Network ID and Host ID
- The representation of the subnet mask is also a 4-byte integer (unsigned)
- The subnet mask is used to extract the network identity (& operation) from the IP address
Understanding Subnet Masks in Depth
设:子网掩码为 M.N.P.Q,则子网可用 IP 地址数量 n = (256 - M) * (256 - N) * (256 - P) * (256 - Q)
例:IP 地址 211.99.34.33,掩码 255.255.2555.248,因此:211.99.34.33 所在子网有 8 个 IP 地址
所在子网地址: 211.99.34.32
广播地址:211.99.34.39
6个可分配地址:211.99.34.33 ... 211.99.34.38
注:子网地址即为网络标识
ip 地址 211.99.34.33, 掩码 255.255.225.248
可知 211.99.34.33 所在子网有 8 个 IP 地址, 且 8 = 2^3(二的三次方),所以 Y = 32 - 3 = 29
可表示为 211.99.34.33 / 29 【简写形式】
注:29 为32位子网掩码的高位
do the math
IP 地址 192.168.3.44,掩码 255.255.255.0
问:
子网地址是什么?广播地址是什么?可用地址有多少?简洁表示法是什么?
答:
子网地址:192.168.3.44
广播地址:192.168.3.255
可用地址:254 [256 - 0(子网地址) - 255(广播地址)]
简洁表示:192.168.3.44 / 24
special address
- 0.0.0.0 / 0 - reserved, often used to represent "default network"
- 127.0.0.0 / 8 - loopback address, commonly used for local software testing
- 255.255.255.255/32 - broadcast address
Address Types in Network Programming
int sock = 0;
struct sockaddr_in addr = {0};
sock = socket(PF_INET, SOCK_STREAM, 0); // Protocol Family,协议族
if (sock == -1) {
pritnf("socket error\n");
return;
}
addr.sin_family = AF_INET; // Address Family,地址族
addr.sin_addr.s_addr = inet_addr("192.168.3.241");
addr.sin_addr.port = htons(8899);
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
printf("connect error\n");
return -1;
}
Question: Will the cast of (struct sockaddr*)&addr
not be a problem?
Address data type resolution
- struct sockaddr can be understood as the top-level address type parent class, which has the same memory layout as the subclass
-
connect()
According toaddr.sin_family
to determine which address type it is and analyze accordingly
IP address related functions
#include <arpa/inet.h>
function prototype | Function description |
in_addr_t inet_addr(const char* strptr); | Convert IP string to network byte order integer |
int inet_aton(const char *cp, struct_addr *inp); | Convert the IP string to an integer conforming to the network byte order, returning 1 for success and 0 for failure |
char *inet_ntoa(struct in_addr in) | Converts an integer address in network byte order to string form |
Programming experiment: address function experiment
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <malloc.h>
int main()
{
unsigned int addr = inet_addr("1.2.3.4");
struct in_addr addr1 = {0x09080706};
struct in_addr addr2 = {0x05040302};
char *s1 = inet_ntoa(addr1);
char *s1_s = strcpy(malloc(32), s1);
char *s2 = inet_ntoa(addr2);
char *s2_s = strcpy(malloc(32), s2);
printf("addr = %x\n", addr);
printf("addr1 = %x\n", addr1.s_addr);
printf("addr2 = %x\n", addr2.s_addr);
printf("s1 = %s\n", s1);
printf("s2 = %s\n", s2); // 注意这里 !!
printf("s1 == s2 : %d\n", s1 == s2); // 注意这里 !!
printf("s1_s = %s\n", s1_s);
printf("s2_s = %s\n", s2_s);
printf("s1_s == s2_s : %d\n", s1_s == s2_s);
if (inet_aton("D.T.Software", &addr1)) { // 注意这里 !!
printf("addr1 = %x\n", addr1.s_addr);
}
free(s1_s);
free(s2_s);
return 0;
}
output
addr = 4030201
addr1 = 9080706
addr2 = 5040302
s1 = 2.3.4.5
s2 = 2.3.4.5 // 注意,转换结果被覆盖 !!
s1 == s2 : 1 // 两次为同一个地址 !!
s1_s = 6.7.8.9
s2_s = 2.3.4.5
s1_s == s2_s : 0
Remaining problem: how to enhance the server's capabilities to support multiple clients at the same time? What is multicast? What is broadcasting?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。