socket的创建、初始化和分配地址

基于Linux的文件操作

  1. Linux中,一切都是文件,socket也是文件的一种,因此网络传输中也可以使用I/O函数。
  2. 文件描述符是系统分配给文件或socket的整数,相当于文件的ID
文件描述符对象
0标准输入
1标准输出
2标准错误

打开文件

int open(const char *path, int flag);

  • path:文件地址
  • flag:文件打开模式
  • 成功时返回文件描述符, 失败时返回-1
打开模式含义
O_CREAT必要时创建文件
O_TRUNC删除全部现用数据
O_APPEND添加数据
O_RDONLY只读
O_WRONLY只写
O_RDWR读写

关闭文件

int close(int fd);

  • 成功时返回0, 失败时返回-1
  • fd:文件描述符

写入操作

ssize_t write(int fd, const void *buf, size_t nbytes);

  • 成功时返回写入的字节数,失败时返回-1
  • fd: 写入对象的文件描述符
  • buf:保存传输数据的缓冲地址值
  • nbytes:传输数据的字节数

读取操作

ssize_t read(int fd, void *buf, size_t nbytes);

  • 成功时返回读取的字节数, 失败时返回-1

socket

socket类型与协议

  1. 协议就是为了实现数据交换的约定;
  2. PF_INET对应IPv4互联网协议族,PF_INET6对应IPv6互联网协议族;
  3. socket类型也就是数据传输方式,有基于TCP面向连接的SOCK_STREAM和基于UDP面向消息的SOCK_DGRAM;
创建socket

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

  • domain:协议族信息
  • type:数据传输类型信息
  • protocol:通信中要使用的协议信息,数据传输方式相同但协议不同时,需要单独指定第三个参数
TCP socket

int tcp_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
int tcp_socket = socket(PF_INET, SOCK_STREAM, 0);

  • 由于满足PF_INET和SOCK_STREAM的只有IPPROTO_TCP,因此第三个参数可以省略
UDP socket

int udp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
int udp_socket = socket(PF_INET, SOCK_DGRAM, 0);

地址族与数据序列

表示IPv4地址的结构体
struct sockaddr_in {
	sa_family_t sin_family;   // 地址族
	unit16_t sin_port;           // 16位TCP/UDP端口号
	struct in_addr sin_addr; // 32位IP地址
	char sin_zero[8];            // 不使用
}
struct in_addr {
	In_addr_t s_addr;
}
  • sin_family
地址族含义
AF_INETIPv4中采用的地址族
AF_INET6IPv6中采用的地址族
AF_LOCAL本地通信采用的UNIX协议的地址族
  • sin_port:以网络字节序(大端)保存
  • sin_addr:以网路字节序保存
网络字节序与地址变换
  1. 大端序: 高位字节存放到低位地址
  2. 小端序:高位字节存放到高位地址
  3. 网络字节序为大端序
  4. Intel和AMD系列CPU都采用小端序
字节序转换
unsigned short htons(unsigned short);
unsigned short ntohs(unsigned short);
unsigned long htons(unsigned long);
unsigned long ntohs(unsigned long);
  • h表示host字节序
  • n表示network字节序

除了向sockaddr_in结构体变量填充数据需要考虑字节序转换问题,其他情况不需要考虑。

网络地址的初始化与分配

  1. 将字符串信息转换为网络字节序

in_addr_t inet_addr(const char *string);

  • 成功时返回32位大端序整数性值,失败时返回INADDR_NONE

下面这种形式更常用!
int inet_aton(const char *string, struct in_addr *addr);

  • 成功时返回1, 失败时返回0
  • string: 字符串地址
  • addr:将保存转换结果的in_addr结构体变量的地址值
  1. 网络地址序转换为字符串地址

char *inet_ntoa(struct in_addr addr);

  • 成功时返回字符串地址值,失败时返回-1
网络地址初始化
  • 服务器端
	struct sockaddr_in serv_adr, clnt_adr;
	memset(&serv_adr, 0, sizeof(serv_adr));
	serv_adr.sin_family = AF_INET;
	serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_adr.sin_port = htons(atoi(argv[1]));

利用常数INADDR_ANY分配服务器端的ip地址,即可以自动获取运行服务器端的ip

  • 向socket分配网络地址

int bind(int sockfd, struct sockddr *myaddr, socklen_t addrlen);

  • 成功时返回0, 失败时返回-1
  • sockfd:要分配地址信息的socket文件描述符
  • myaddr:存有地址信息的结构体变量地址值
  • addrlen:myaddr的长度
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值