【计算机网络】Socket编程接口

一、sockaddr结构体

套接字种类很多,例如:网络套接字、原始套接字、unix域间套接字

三种套接字就要设计三套接口吗?不用,利用struct sockaddr复用同一套接口

如果是网络套接字编程:使用socket相关函数时,传参传递的是 struct sockaddr_in

如果是unix域间套接字编程:使用socket相关函数时,传参传递的是 struct sockaddr_un

二、Socket常见接口

1. socket()

int socket(int domain, int type, int protocol); // 创建socket文件描述符

① int domain: 协议版本 -> 网络通信(AF_INET)

② int type: SOCK_DGRAM(数据报服务) -> UDP;SOCK_STREAM(流式服务) -> TCP

③ int protocol : 默认填0即可

④ 返回值:返回一个文件描述符,利用这个fd进行读写

2. bind()

int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen); // 将sockfd和套接字绑定

① int sockfd:要绑定的socket文件描述符

② struct sockaddr *my_addr:要绑定的套接字

③ socklen_t addrlen:struct sockaddr *my_addr的长度 -> sizeof(my_addr)

④ 返回值:绑定成功返回0;绑定失败返回-1

3. recvfrom()

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen); // 接收数据(接收方读数据)适用于UDP

① int sockfd:接收方的socket文件描述符

② void *buf:读到/接收到 的数据放到buf缓冲区里

③ size_t len:buf的长度 -> sizeof(buf)

④ int flags:填0 -> 阻塞式

⑤ struct sockaddr *src_addr:谁发的(发送方的ip/port)

⑥ socklen_t *addrlen:struct sockaddr *src_addr的长度 -> sizeof(src_addr)

⑦ 返回值:读到的数据的长度


struct sockaddr *src_addr, socklen_t *addrlen:输出型参数 -> 输出发送方的ip/port

用法:创建struct sockaddr_in结构体,在强转成struct sockaddr结构体

// 读取数据
struct sockaddr_in peer;
socklen_t len = sizeof(peer);                                                                 
ssize_t s = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &len);

// 知道是谁发的
std::string ip = inet_ntoa(peer.sin_addr); // IP
uint16_t port = ntohs(peer.sin_port);      // port

4. sendto()

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen); // 发送数据(发送方发数据)适用于UDP

① int sockfd:发送方的socket文件描述符

② const void *buf:要发出去的 的数据放到buf缓冲区里

③ size_t len:buf的长度 -> sizeof(buf)

④ int flags:填0 -> 阻塞式

⑤ const struct sockaddr *dest_addr:发给谁(接收方的ip/port)

⑥ socklen_t addrlen:const struct sockaddr *dest_addr的长度 -> sizeof(dest_addr)

⑦ 返回值:发送的数据的长度


const struct sockaddr *dest_addr, socklen_t addrlen:输入型参数 -> 输入目的地ip/port

用法:创建struct sockaddr_in结构体来填写对方信息,在强转成struct sockaddr结构体

// 填写目的地信息(假设是客户端发给服务器)
struct sockaddr_in client;
bzero(&client, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons(clientport);
client.sin_addr.s_addr = inet_addr(clientip.c_str());

// 发送消息
sendto(sockfd, response_message.c_str(), response_message.size(), 0, (struct sockaddr*)&client, sizeof(client));

5. listen()

int listen(int s, int backlog); // 设置socket为监听状态 TCP

设置后的sockfd 不是用来进行数据通信的,而是用来监听链接到来,获取新链接的

① int s:要设置的socket文件描述符

② int backlog:同时请求连接的最大个数(还未建立连接)

③ 返回值:成功返回0;失败返回-1

6. accept()

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); // 获取连接 TCP

① int sockfd:socket()创建sockfd -> listen()设置成listen状态 -> 传入listensock

② struct sockaddr *addr:谁来建立的连接,就是谁的套接字

③ socklen_t *addrlen:struct sockaddr *addr的长度 -> sizeof(addr)

④ 返回值:返回一个文件描述符,用于和client进行通信的fd

7. connect()

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); // 建立连接 TCP

① int sockfd:建立连接的sockfd

② const struct sockaddr *addr:对方的套接字

③ socklen_t addrlen:const struct sockaddr *addr的长度 -> sizeof(addr)

④ 返回值:成功返回0;失败返回-1


总结:用一幅图表示个函数之间的关系

三、基本转换函数

1. 与port有关的转换

2.与ip有关的转换

IP地址的表示有两种:点分十进制表示和整数表示

"192.168.1.100" -> 点分十进制风格的IP -> 字符串形式,可读性好

uint32_t ip; -> 整数风格的IP -> 网络通信使用

(1)inet_addr

in_addr_t inet_addr(const char *cp); // 点分十进制表示 -> 整数表示

函数内部完成两个工作:①点分十进制IP -> uint32_t    ②htonl()

(2)inet_ntoa

char *inet_ntoa(struct in_addr in); // 整数表示 -> 点分十进制表示

函数内部完成两个工作:①ntohl()    ②uint32_t -> 点分十进制IP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值