mirror of
https://github.com/Hizenberg469/Network-Programming-in-C.git
synced 2026-04-20 01:32:23 +03:00
238 lines
5.6 KiB
Markdown
238 lines
5.6 KiB
Markdown
# Network Programming in C
|
|
|
|
Quick reference to `struct`(s) and apis' used for networking applicaton in C language.
|
|
|
|
Let's first discuss about the important `struct` and then how we use apis' to establish networking functionality.
|
|
|
|
## struct(s) used are :-
|
|
|
|
* **struct** addrinfo -
|
|
|
|
```
|
|
struct addrinfo {
|
|
int ai_flags; // AI_PASSIVE, AI_CANONNAME, etc.
|
|
int ai_family; // AF_INET, AF_INET6, AF_UNSPEC
|
|
int ai_socktype; // SOCK_STREAM, SOCK_DRAM
|
|
int ai_protocol; // use 0 for "any"
|
|
size_t ai_addrlen; // size of ai_addr in bytes
|
|
struct scokaddr *addr; // struct sockaddr_in or _in6
|
|
char *ai_canonname; // full canonical hostname
|
|
struct addrinfo *ai_next; // linked list, next node
|
|
};
|
|
```
|
|
|
|
1. ai_flags :
|
|
|
|
Type : `int`
|
|
|
|
Value : `AI_PASSIVE`, `AI_CANONNAME`.
|
|
|
|
Purpose : Help determine the processing path for `getaddrinfo()`.
|
|
|
|
* For ex : `AI_PASSIVE` suggest the `getaddrinfo()` to get the address of the host machine the program is running on.
|
|
|
|
2. ai_family :
|
|
|
|
Type : `int`
|
|
|
|
Value : `AF_INET (IPv4)`, `AF_INET6 (IPv6)` or `AF_UNSPEC`.
|
|
|
|
Purpose : Specify which type of IP address (in terms of representation) does it hold.
|
|
|
|
3. ai_socktype :
|
|
|
|
Type : `int`
|
|
|
|
Value : `SOCK_STREAM`, `SOCK_DRAM`.
|
|
|
|
Purpose : Specify what kind of socket we are interested in using.
|
|
|
|
4. ai_protocol :
|
|
|
|
Type : `int`
|
|
|
|
Value : use 0 for "any".
|
|
|
|
Purpose : What kind of protocol we are intending to use.
|
|
|
|
5. ai_addrlen :
|
|
|
|
Type : `size_t`
|
|
|
|
Value : size of ai_addr in bytes.
|
|
|
|
Purpose : What is the size of struct sockaddr pointer holds.
|
|
|
|
6. addr :
|
|
|
|
Type : `struct sockaddr *`
|
|
|
|
Value : address in form of `struct sockaddr`.
|
|
|
|
Purpose : Holding the actual address.
|
|
|
|
7. ai_cannonname :
|
|
|
|
Type : `char *`
|
|
|
|
*I don't know what's it's used for.*
|
|
|
|
8. ai_next :
|
|
|
|
Type : `struct addrinfo *`
|
|
|
|
Value : address of next `struct addrinfo`.
|
|
|
|
Purpose : Intending to have a linked list.
|
|
|
|
---
|
|
|
|
* **struct** sockaddr -
|
|
|
|
```
|
|
struct sockaddr{
|
|
unsigned short sa_family; // Address family, AF_XXX
|
|
char sa_data[14]; // 14 bytes of protocol address
|
|
};
|
|
```
|
|
|
|
1. sa_family :
|
|
|
|
Type : `unsigned short`
|
|
|
|
Value : `AF_XXX`
|
|
|
|
Purpose : Specify the address family type.
|
|
|
|
2. sa_data :
|
|
|
|
Type : `char`
|
|
|
|
Value : IP address in for raw byte data.
|
|
|
|
Purpose : Buffer for storing the actual address in *Network Byte Order*.
|
|
|
|
> [!IMPORTANT]
|
|
> Using this structure and hard coding every thing on it is very tedious. Use `struct sockaddr_in` for IPv4 or `struct sockaddr_in6` for IPv6.
|
|
---
|
|
|
|
* **struct** sockaddr_in -
|
|
|
|
```
|
|
struct sockaddr_in{
|
|
short int sin_family; // Address family, AF_INET
|
|
unsigned short int sin_port; // Port number
|
|
struct in_addr sin_addr; // Internet address
|
|
unsigned char sin_zero[8]; // Same size as struct sockaddr
|
|
};
|
|
```
|
|
|
|
1. sin_family :
|
|
|
|
Type : `short int`
|
|
|
|
Value : `AF_INET`.
|
|
|
|
Purpose : Specifying the IP address belongs to IPv4.
|
|
|
|
2. sin_port :
|
|
|
|
Type : `unsigned short int`
|
|
|
|
Value : Port number.
|
|
|
|
Purpose : Stores the port number which will be used by the created socket.
|
|
|
|
3. sin_addr :
|
|
|
|
Type : `struct in_addr`
|
|
|
|
Value : Internet address
|
|
|
|
Purpose : Act as a buffer to store Internet address in raw byte.
|
|
|
|
4. sin_zero :
|
|
|
|
Type : `unsigned char`
|
|
|
|
Value : All element set to zero.
|
|
|
|
Purpose : Used for padding to match the size of `struct sockaddr`.
|
|
|
|
|
|
* **struct** in_addr -
|
|
|
|
```
|
|
struct in_addr{
|
|
uint32_t s_addr;
|
|
};
|
|
```
|
|
|
|
1. s_addr :
|
|
|
|
Type : `uint32_t`
|
|
|
|
Value : IP address in raw byte in Network Byte Order.
|
|
|
|
Purpose : Act as buffer to store IP address.
|
|
|
|
---
|
|
|
|
* **struct** sockaddr_in6 -
|
|
|
|
```
|
|
struct sockaddr_in6{
|
|
u_int16_t sin6_family; // address family, AF_INET6
|
|
u_int16_t sin6_port; // port number, Network Byte Order
|
|
u_int32_t sin6_flowinfo;// IPv6 flow information
|
|
struct in6_addr sin6_addr; // IPv6 address
|
|
u_int32_t sin6_scope_id;// Scope ID
|
|
};
|
|
```
|
|
|
|
> `sin6_family`, `sin6_port` and `sin6_addr` are similar to the corresponding fields of `struct sockaddr_in6`.
|
|
|
|
* **struct** in6_addr -
|
|
|
|
```
|
|
struct in6_addr{
|
|
unsigned char s6_addr[16]; //IPv6 address
|
|
};
|
|
```
|
|
|
|
1. s6_addr :
|
|
|
|
Type : `unsigned char array`
|
|
|
|
Value : IPv6 address in raw byte.
|
|
|
|
Purpose : Act as a buffer to store IPv6 address.
|
|
|
|
---
|
|
|
|
* **struct** sockaddr_storage -
|
|
|
|
> [!IMPORTANT]
|
|
> Because `sockaddr_in6` is larger in size than `sockaddr_in` and we may not know which to use when, we can use `sockaddr_storage` for storing any of the two and type-cast to their respective type.
|
|
|
|
```
|
|
struct sockaddr_storage{
|
|
sa_family_t ss_family; // address family
|
|
|
|
/*
|
|
* all this is padding, implementation specific, ignore it.
|
|
*/
|
|
|
|
char __ss_pad1[_SS_PAD1SIZE];
|
|
int64_t __ss_align;
|
|
char __ss_pad2[_SS_PAD2SIZE];
|
|
};
|
|
```
|
|
|
|
1. ss_family :
|
|
|
|
Type : `sa_family_t`
|
|
|
|
Value : `AF_INET` or `AF_INET6`.
|
|
|
|
Purpose : To distinguish address family it contains. |