关于一些网络编程的常识整理。linux
1.网络数据传输到咱们的计算机,是如何知道传输给那个应用?
经过端口,因此端口也是不能重复占用的。编程
typedef struct sockaddr_in { #if(_WIN32_WINNT < 0x0600) short sin_family; #else //(_WIN32_WINNT < 0x0600) ADDRESS_FAMILY sin_family; #endif //(_WIN32_WINNT < 0x0600) USHORT sin_port; IN_ADDR sin_addr; CHAR sin_zero[8]; } SOCKADDR_IN, *PSOCKADDR_IN;
1.sin_family 设置的为地址族
2.sin_port 为端口号,16位也就是两个字节,因此端口范围是1-65535,其中1-1000是系统保留的端口号,可是并非咱们不能用,只是最后不用。
1024-5000: BSD临时端口,通常的应用程序使用1024到4999来进行通信;
5001-65535: BSD服务器(非特权)端口,用来给用户自定义端口.服务器
ip 地址的定义
typedef struct in_addr {
union {
struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { USHORT s_w1,s_w2; } S_un_w;
ULONG S_addr;
} S_un;网络
typedef struct sockaddr { #if (_WIN32_WINNT < 0x0600) u_short sa_family; #else ADDRESS_FAMILY sa_family; // Address family. #endif //(_WIN32_WINNT < 0x0600) CHAR sa_data[14]; // Up to 14 bytes of direct address. } SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
只是由于CHAR sa_data[14];保存ip与端口过于麻烦,多出的部分补充为0,因此引用了sockaddr_in来人性化操做。tcp
5.cpu 向内存中保存数据的方式有两种。函数
大端序:高位字节存放在低位地址。
小端序:高位字节存放在高位地址。
例如: int32 数字1,二进制 00000000 00000000 00000000 00000001
这种就是大端序。
而后小端序是:00000001 00000000 00000000 00000000
由于咱们传递的时候实际上传递的是信号,也就是二进制。
若是大端号遇到小端号,他们接收的数据正确可是理解是不同的。
因此在传输数据的时候约定所有转换成大端序。
因此有了下面几个函数:code
unsigned short htons(unsigned short); unsigned short ntohs(unsigned short); unsigned long htonl(unsigned long); unsigned long htonl(unsigned long);
h:主机字节序
t:to
n:网络字节序
s:short
l:long
之因此有long,由于long在linux 中为4个字节,能够用来转换ip
htons 用来转换端口。
因此传输地址为:server
serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); serverAddr.sin_port = htons(atoi(argv[1]));
INADDR_ANY是一个自动获取的内部ip,好比说127.0.0.1,这只是针对只有一个ip地址的状况,若是本身内部虚拟了网络,那么这个最后去手动填写。
实际过程当中咱们赋值是:tcp-ip
addr='127.0.0.1' inet_aton(addr,&addr_inet.sin_addr);
功能以下:好比说咱们写地址的时候是:127.0.0.1
那么这个时候其实咱们必须转换为32位的int类型,也就是32byte。
inet_aton就是用来转换的,避免咱们手动计算。ip