linux 网络编程-基础篇

#Socket简介

是一个编程接口

是一种特殊的文件描述符(everything in Unix is a file)

并不仅限于TCPIP协议

面向连接(Transmission Control Protocol - TCPIP)

无连接(User Datagram Protocol-UDP 和 Inter-Network Packet Exchange-IPX)

#Socket类型

流式套接字(SOCK_STREAM)

提供了一个面向连接,可靠的数据传输服务,数据无差错,无重复的发送且

按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是

字节流,无长度限制

数据报套接字(SOCK_DGRAM)

提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,

数据可能丢失或重复,顺序发送,可能乱序接收

原始套接字(SOCK_RAW)

可以对较低层次协议如IP,ICMP直接访问

#IP地址

IP地址是Internet中主机的标识

Internet中的主机要与别的机器通信必须具有一个IP地址

IP地址为32位(IPV4)或者128位(IPV6)

每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包

选择路由

表示形式:常用点分形式,如202.38.64.10,最后都会转换为一个32位的无符号

整数。

#IP地址的转换

inet_aton()

将strptr所指的字符串转换成32位的网络字节序二进制值

int inet_aton(const char *strptr, struct in_addr *addrptr);

inet_addr()

功能同上,返回转换后的地址

in_addr_t inet_addr(const char *strptr);

inet_ntoa()

将32位网络字节序二进制地址转换成点分十进制的字符串。

char *inet_ntoa(struct in_addr inaddr);

#端口号

为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号

来区分

TCP端口号与UDP端口号独立(协议不同可以使用同一个端口)

三无组:协议,IP,端口

端口号一般由IANA(Internet Assigned Numbers Authority)管理

众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由

UNIX系统占用

已登记端口:1024~49151

动态或私有端口:49152~65535

#字节序

不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO):

小端序(little-endian)-低字节存储在低地址

将低字节存储在起始地址,称为"Little-Endian"字节序,Intel,AMD等

采用的是这种方式

大端序(big-endian)-高序字节存储在低地址

将高字节存储在起始地址,称为"Big-Endian"字节序,由ARM,Motorola

等所采用

网络中传输的数据必须按网络字节序,即大端字节序

在大部分PC机上,当应用进程将整数送入socket前,需要转化成网络字节序;当

应用进程从socket取出整数后,要转化成小端字节序

#字节序转换函数

把给定系统所采用的字节序称为主机字节序,为了避免不同类别主机之间在数据

交换时由于对于字节序的不用而导致的差错,引入了网络字节序

主机字节序到网络字节序:

u_long htonl(u_long hostlong);

u_short htons(u_short short);

网络字节序到主机字节序

u_long ntohl(u_long hostlong);

u_short ntohs(u_short short);

#网络编程相关API

int Socket(int domain, int type, int protocol);

int bind(int Sockfd, struct sockaddr *my_addr, int addrlen);

int listen(int sockfd, in backlog);

int accept(int sockfd, struct sockaddr *addr, Socklen_t *addrlen);

int connect(int sockfd, const struct sockaddr *addr, Socklen_t addrlen);

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,

const struct sockaddr *dest_addr, Socklen_t addrlen);

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,

struct sockaddr *src_addr, Socklen_t *addrlen);

int shutdown(int sockfd, int how);

#command:

netstat -anpt

#地址结构的一般用法

1.定义一个struct sockaddr_in类型的变量并清空

struct sockaddr_in myaddr;

memset(&myaddr, 0, sizeof(myaddr));

2.填充地址信息

myaddr.sin_family = PF_INET;

myaddr.sin_port = htons(8888);

myaddr.sin_addr.s_addr = inet_addr("192.168.1.100");

3.将该变量强制转换为struct sockaddr类型在函数中使用

bind(listenfd,(struct sockaddr *)&myaddr, sizeof(myaddr));

#地址转换函数

unsigned long inet_addr(const char *address);

int inet_aton(const char *cp, struct in_addr *inp);

char *inet_ntoa(struct in_addr in);

socket流程图:

你可能感兴趣的:(linux 网络编程-基础篇)