IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Socket编程基本函数与相关结构 -> 正文阅读

[网络协议]Socket编程基本函数与相关结构

Socket编程基本函数

Socket通信创建流程图
Socket通信基本流程图
学课的时候写了个小demo,看完下面的函数可以看看demo中的实例

sokcet 函数

功能简述:socket() 打开一个网络通讯端口。类似文件操作open()返回一个文件操作符。

如果socket()调用出错返回-1。


// 函数原型

#include <sys/types.h>

#include <sys/socket.h>

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

// 参数

domain:AF_INET用来产生socket的协议,使用TCP或UDP来传输,用IPv4的地址。

                AF_INET6 行为与IPv4类似,使用IPv6地址

                AF_UNIX本地协议,使用在Unix和Linux系统上。一般当客户端和服务器在同一台及其上的时候使用

type:

            SOCK_STRAM这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。是使用最多的

            SOCK_DGRAM这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行连接

            SOCK_SEQOACKET该协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把包传输完整才能进行读取。

             SOCK_RAW socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)

             SOCK_RDM这个类型是很少使用的,在大部分操作系统中未实现,提供给数据链路层使用,不保证数据包的顺序

protocol:0 表示默认协议

返回值

    成功:返回指向新创建的socket文件操作符。

    失败:返回-1,设置errno

对于IPv4,domaindomain参数指定为AF_INET。

对于TCP协议,type参数指定为SOCK_STREAM,表示面向流的传输协议。

对于UDP协议,type参数指定为SOCK_DGRAM,表示面向数据包的传输协议。


bind函数

功能简述:绑定一个固定的网络地址和端口号接收客户端发起的连接

// 函数原型
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd,const struct sockaddr* addr,socklen_t addrlen);
// 参数
	sockfd:创建的socket文件描述符。即文件操作符。
	addr:构造出IP地址加端口号
	addrlen:sizeof(addr)长度
// 返回值:
	成功返回0
	失败返回-1 设置errno

bind()的作用是将sockfd和addr绑定在一起。使sockfd这个文件操作符监听addr所描述的地址和端口号。struct sockaddr* 是一个通用的指针类型。addr参数可以接受多种协议的sockaddr结构体,而他们的长度不相同,所以需要第三个参数addrlen指定结构体的长度

listen函数

listen声明sockfd处于监听状态,并且规定最多多少个连接处于待连接状态。如果超过规定数量连接请求就忽略。

#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd,int backlog);
sockfd:
	socket文件操作符
backlog:
	在Linux系统中,指排队等待建立3次握手队列的长度

使用说明:当客户端发起来连接而服务器来不急处理。尚未被接收的客户端处于待连接状态,如果收到超过一定数量级的连接等待就忽略。

accept函数

使用场景:三次握手是在客户端Connect、服务端Listen后,三次握手完成后服务器调用accept()接受连接。如果没有连接请求,就阻塞等待直到有客户端连接。

#include <sys/types.h> 
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockdf:
	socket文件描述符
addr:
	传出参数,返回链接客户端地址信息,含IP地址和端口号
addrlen:
	传入传出参数(值-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小
返回值:
	成功返回一个新的socket文件描述符,用于和客户端通信,失败返回-1,设置errno
connect函数

客户端调用connect函数连接服务器

#include <sys/types.h> 					/* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockdf:
	socket文件描述符
addr:
	传入参数,指定服务器端地址信息,含IP地址和端口号
addrlen:
	传入参数,传入sizeof(addr)大小
返回值:
	成功返回0,失败返回-1,设置errno
出错处理函数

函数执行出错打印出错信息

#include <errno.h>
#include <string.h>
char *strerror(int errnum);     /* See NOTES */
errnum:
	传入参数,错误编号的值,一般取 errno 的值
返回值:
	错误原因
#include <stdio.h>
#include <errno.h>
void perror(const char *s);    /* See NOTES */
s:
	传入参数,自定义的描述
返回值:
	无
向标准出错stderr 输出出错原因  

相关结构
sockaddr结构

sockaddr 传递一个地址给函数(void *)。至于这个函数使用sockadd_in还是其他由地址族确定,然后函数强制转换为所需地址类型
在这里插入图片描述

struct sockaddr{
	sa_family_t sa_family; /*地址协议族,AF_xxx*/
	char sa_data[14];
};
struct sockaddr_in{
	sa_family_t sin_family;
	in_port_t sin_port;	/*port in network byte order*/
	struct in_addr sin_addr; /*internet address*/
};
/*Internet address*/
struct in_addr
{
	uint32_t s_addr;
};

因为sock API早于ANSI C标准化。当时没有void * 类型。因此bind、accept函数的参数在传递之前需要强制转换。

struct sockaddr_in servaddr;
bind(listen_fd,(struct_sockaddr*)servaddr,sizeof(servaddr));
sockaddr_in使用实例:
struct sockaddr_in servaddr;
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(6666);

首先将整个结构体清零,然后设置地址类型为AF_INET,网络地址为INADDR_ANY,这个宏表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也可能绑定多个IP地址,这样设置可以在所有的IP地址上监听,直到与某个客户端建立了连接时才确定下来到底用哪个IP地址,端口号为6666。

字节序转换

网络数据流同样有大小端之分。发送主机通常将发送缓冲区中的数据按内存地址从高到低的顺序发出,接收主机把从网络接到的字节一次保存在接收缓冲区内,也是按内存地址从低到高的顺序保存。网络数据流的地址:先发出的数据是低地址,后发出的数据是高地址
TCP/IP协议规定:网络数据流采用大端字节序,及低地址高字节。
因为操作系统的不同设计,所以在通信过程中不同操作系统可能采用不同字节序。所以在通信前数据需要转换字节序。

// 网络字节序和主机字节序的转换相关函数
#include <apra/inet.h>
/* 把主机字节序转换为32位网络字节序*/
uint32_t htonl(uint32_t hostlong);
/* 把主机字节序转换为16位网络字节序*/
uint16_t htons(uint16_t hostshort);
/* 把网络字节序转换为32位主机字节序*/
uint32_t ntohl(uint32_t netlong);
/* 把网络字节序转换为16位主机字节序*/
uint16_t ntohs(uint16_t netshort);

IP转换函数:IP转换函数进行IP字节序的转换。

// 函数原型
#include <apra/inet.h>
int inet_pton(int af,const char* src,void *dst);
const char* inet_ntop(int af,const void* src,char *dst,socklen_t size);
/*
 af:AF_INET或AF_INET6。即对应支持IPV4和IPV6
 sec:所需转换的地址
*/

inet_pton 、inet_ntop不仅可以转换IPV4的inet_addr。还可以转换IPV6的in6_addr。
因此函数接口是 void* addrptr。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-12 13:30:30  更:2021-09-12 13:31:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 11:08:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计