Socket编程---API

Socket可以看成是用户进程与内核网络协议栈的编程接口
Socket不仅可以用于本机的进程间通信,还可以用于网络上不同主机间的通信。
Socket编程---API_第1张图片
IPv4套接口地址结构
IPv4套接口地址结构通常也称为“网际套接字地址结构”,它以“sockaddr_in”命名,定义在头文件中

struct sockaddr_in{
	uint8_t sin_len;//整个sockaddr_in结构体长度
	sa_family_t sin_family;//指定该地址家族,在这里必须设为AF_INET
	in_port_t sin_port;//端口
	struct in_addr sin_addr;//IPV4地址
	char sin_zero[8];//暂不使用,一般设置为0;
}

通用地址结构
通用地址结构用来指定与套接字关联的地址

struct sockaddr{
	uint8_t sin_len;//整个sockaddr结构体的长度
	sa_family_t sin_family;//指定该地址家族
	char sa_data[14];//14,有sin_family决定他的形势
}

上面两个地址结构的大小是相等的。

端口号是什么?
一台主机可以用一个ip来标识,那么主机中的进程用什么标识呢,用端口号。知名端口号0到1023分配给了一些固定服务,比如FTP:21、HTTP:80等等。1024到65535动态分配,应用程序的区分用端口号。

字节序
int a=0x12345678
大端模式:

在这里插入图片描述
数值小的放到高位,大端模式

小端模式:
在这里插入图片描述
数值大的放到低位,小端模式
那么如何测试自己电脑什么模式呢?

int main() {
	int a = 0x12345678;
	char *p = (char *)&a;
	printf("%x,%x,%x,%x", p[0], p[1], p[2], p[3]);
	return 0;
}

结果如下:
在这里插入图片描述
所以我的为小端模式。

网络也有网络在字节序,在两个不同主机进行通信的时候

本地字节序--->网络字节序--->本地字节序

字节序转换函数

//h代表host,n代表networks,s代表short,l代表long
uint32_t htonl(uint32_t hostlong);  //主机long转成网络long
uint16_t htons(uint16_t hostshort); //主机short转成网络short
uint32_t ntohl(uint32_t netlong);   //网络long转成网络long
uint16_t ntohs(uint16_t netshort);  //网络short转成网络short

这里插一个问题,这个uint32_t、uint16_t是什么意思呢?
其实在linux中以_t结尾的都是自定义类型。为什么这样做呢?

typedef unsigned int size_t;//四个字节32位。
但是我们需要将数据类型大小变成64位时,如果我们使用的是:
unsigned int a;
unsigned int b;
是不是需要将所有的unsigned int 变成long long
long a;
long b;
这样的话比较麻烦。
如果我们这样定义的呢?
size_t a;
size_t b;
size_t c;
我们只需要将typedef unsigned int size_t;改为:typedef long long size_t;就可以了方便开发。

地址转换函数

在tcp/ip中ipv4是32位====>192.168.3.22(点分式的ip)

#include
#include

typedef uint32_t in_addr_t;
struct in_addr {
	in_addr_t s_addr;
};


int inet_aton(const char *cp,struct in_addr *inp);//将192.168.3.22转换成一个32位整数
int_addr_t inet_addr(const char *cp);//将cp(192.168.322)转换成一个struct in_addr结构
char * inet_ntoa(struct in_addr in);//借用了你的内存,将结构struct int_addr转换成一个点分式的ip(192.168.3.22)

Socket编程---API_第2张图片socket函数

#include           /* See NOTES */
#include 
//创建一个套接字用于通信
/*
*@domain:指定通信协议族(protocol family)
*@type:指定socket类型,流式套接字SOCK_STREAM(tcp),数据报套接字SOCK_DGRAM(udp),原始套机子SOCK_RAW
*@protocol:协议类型
*@return 成功返回非负整数,与文件描述符类似,称为套接口描述字,简称套接字,失败返回-1;
*/
int socket(int domain, int type, int protocol);
//实际返回一个文件句柄

bind函数

#include           /* See NOTES */
#include 
//绑定本地地址到套接字
/*
*@sockfd socket函数返回的套接字
*@addr	要绑定的地址
*@addrlen:地址长度
*@return:成功放回0,失败返回-1
*/
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

listen函数

#include           /* See NOTES */
#include 
//一般来说,listen函数应该在抵用socket和bind函数之后,嗲用函数accept之前调用
//对于给定的监听套接口,内核要维护两个队列:
//1、已由客户端发出并到达服务器,服务器正在等待完成相应的tcp三次握手过程
//2、已完成三次握手的连接的队列
int listen(int sockfd, int backlog);

accept函数

#include           /* See NOTES */
#include 
/*
*@sockfd:服务器套接字
*@addr:将返回等待对方的套接字地址
*@addrlen:返回等待方的套接字地址长度
*/
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

connect函数

#include           /* See NOTES */
#include 
/*
*@sockfd:未连接套接字
*@addr:要连接的套接字地址
*@addrlen:第二个参数addr长度
*@return:成功返回0,失败返回-1
*/
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

你可能感兴趣的:(Linux,操作系统,计算机网络)