网络编程1-基本概念、函数接口

一、网络基本概要

1、网络通信概念:

不同主机的进程间通信

2、IP地址:

  • 概念:类似于就是网络中身份证 ---- 用来唯一的标识一台主机 ,由网络地址和主机号组成
    • 便于记忆,利用点分十进制表示法(类似于192.168.1.1)
    • 主机号为0的IP地址是网络地址,主机号为255的地址是广播地址

3、子网掩码:

  • 概念:用来区分IP地址中的网络地址和主机地址,搭配IP地址使用
    • 子网掩码1:对应IP地址的网络位
    • 子网掩码0:对应IP地址的主机位

4、端口号:

  • 概念:16位的数值0-65535
  • 作用:唯一的标识一个进程,每一个应用的进程都有一个端口号,通讯时用来区分数据包属于哪个进程
  • 分类
    • 任何TCP/IP实现所提供的服务都用1-1023之间的端口号:
      • http:80 FTP:20/2 HTTPS: 443 TFPT: 69
    • 端口号从1024-49151是被注册的端口号,被IANA指定为特殊服务使用
    • 从49152-65535是动态或私有端口号
      • 所以代码调试时,常使用端口号50000的

5、网络配置:

  • ping IP地址/域名
  • ifconfig 查看当前操作系统中网卡信息
    • ens33:虚拟机中的网卡
    • lo:回环地址(127.0.0.1)
    • inet:IPv4地址
    • netmask:子网掩码
    • broadcast:广播号
    • inet6:IPv6地址
    • ether:MAC地址

6、国际网络体系结构

  • OSI模型: open system interconnect 理论模型
    • 应用层:要传输的数据信息,如文件传输,电子邮件等
    • 表示层:数据加密,解密操作,压缩,解压缩
    • 会话层:建立数据传输通道
    • 传输层:传输的方式 UDP TCP 端口
    • 网络层:实现数据路由 路由器 ip
    • 数据链路层:封装成帧,点对点通信(局域网内通信),差错检测 交换机 ARP
    • 物理层:定义物理设备标准,比如网线,光纤等传输介质 比特流 bit 0 1
  • TCP/IP模型: 工业模型 4层
    • 应用层:HTTP、HTTPS、FTP、TFTP、MQTT
    • 传输层:TCP、UDP
    • 网络层:IP
    • 网络接口层:网络接口层既是传输数据的物理媒介,也可以为网络层提供一条准确无误的线
  • TCP模型:5层
    • 应用层:HTTP、HTTPS、FTP、TFTP、MQTT
      • 传输层:TCP、UDP
      • 网络层:IP
      • 数据链路层:封装成帧,点对点通信(局域网内通信),差错检测 交换机
      • 物理层:定义物理设备标准,比如网线,光纤等传输介质 比特流 bit

7、基本协议:

  • 应用层协议:
    • FTP:文件传输协议(实现文件上传/下载)
    • TFTP:简单文件传输协议(实现文件上传/下载)
    • HTTP:超文本传输协议(实现超文本(集视频、图片、文字于一体的文件类型)传输)
    • HTTPS:加密版超文本传输协议
    • MQTT:消息队列遥测传输协议(物联网传输)
  • 传输层协议:
    • UDP:用户数据报协议
    • TCP:传输控制协议

8、TCP与UDP协议

  • TCP(即传输控制协议)
    • 特点:面向连接、可靠、字节流
    • 注重于:可靠性、稳定性
    • 实际应用:类似打电话
    • 是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、数据无失序、数据无重复到达的通信)
    • 适用情况:
      • 适合于对传输质量要求较高,以及传输大量数据的通信。
      • 在需要可靠数据传输的场合,通常使用TCP协议
      • MSN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议
  • UDP(用户数据报协议)
    • 特点:无连接、不可靠、数据报
    • 注重于:实时性、效率高
    • 实际应用:早期监控(似直播,有服务器接收)想要稳定(会借鉴tcp的协议,稳定性)
    • 可靠的无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。
    • 适用情况:
      • 发送小尺寸数据(如对DNS服务器进行IP地址查询时)
      • 在接收到数据,给出应答较困难的网络中使用UDP。(如:无
        线网络)
      • 适合于广播/组播式通信中。
      • MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通
        讯通常采用UDP协议
      • 流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP
        方式进行实时数据传输

二、函数接口

1、socket

原型:

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

头文件:

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>

功能:

创建一个套接字文件(用来通信的接口(文件描述符))

参数:

  • domain:协议族/地址族(address family)
    • 常用[AF_INET]、[AF_INET6]
  • typ:数据传输方式
    • 常用[SOCK_STREAM]、[SOCK_DGRAM]
  • protocol:协议
    • 通常为0,表示让系统自动选择最匹配的协议

返回值:

成功:返回socket对应的文件描述符(fd)

失败:返回-1

IPv4地址形式:
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
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; /* address in network byte order */
};

2、send

类似于write

函数原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,

const struct sockaddr *dest_addr, socklen_t addrlen);

功能: 向socket中发送信息

参数: sockfd:要操作的socket

buf :存放数据的空间

len :buf的大小

flags :指定读取信息的操作标志-MSG_DONTWAI

返回值:

成功返回实际发送字节数

失败返回-1

3、sendto

函数原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,

const struct sockaddr *dest_addr, socklen_t addrlen);

功能:

向一个IP地址和端口发送数据信息

端口号:区分一台主机不同的应用程序(0 - 65535)

参数:

sockfd:套接字文件描述符

buf:发送数据空间首地址

len:发送数据的长度

flags:发送数据属性(默认为0)

dest_addr:目的IP地址和端口

addrlen:目的IP地址和端口的长度

返回值:

成功返回实际发送字节数

失败返回-1

4、recv

类似于read

函数原型:ssize_t recv(int sockfd, void *buf, size_t len , int flags);

功能: 从socket中接收信息

参数: sockfd:要操作的socket

buf :存放数据的空间

len :buf的大小

flags :指定读取信息的操作标志-MSG_DONTWAI

返回值: 成功 读取到的字节数

失败-1

5、recvfrom

函数原型: ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,

struct sockaddr *src_addr, socklen_t *addrlen);

功能: 接收网络发送的数据信息

参数: sockfd:套接字文件描述符

buf:发送数据空间首地址

len:最大能够接收的数据个数

flags:属性默认为0

src_addr:存放发送端IP地址信息的空间首地址

addrlen:想要接收的数据长度的空间首地址

返回值: 成功返回实际接收字节数

失败返回-1

具有阻塞功能(直到接收到数据,才会继续向下执行)

4、htons主机转网络字节序

  • 主机:小端或者大端 ----host
  • 网络:统一大端 ----network
    • uint32_t htonl(uint32_t hostlong); 主机转网络
    • uint16_t htons(uint16_t hostshort); 主机转网络
    • uint32_t ntohl(uint32_t netlong); 网络转主机
    • uint16_t ntohs (uint16_t netshort); 网络转主机
      • h:host、n:net、l:long、s:short

5、inet_addr与inet_ntoa

函数原型: in_addr_t inet_addr(const char *cp);

功能: 将字符串IP地址转换成二进制IP地址形式

cp 表示要用的ip地址的字符串 //点分十进制

函数原型: char *inet_ntoa(struct in_addr in);

功能: 将二进制ip转换成字符串

5、bind

函数原型: int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

功能: 将一个套接字与IP地址和端口号绑定(只能绑定自己的IP地址)

参数: sockfd:套接字文件描述符

addr:IP地址和端口号结构体首地址

addrlen:长度

返回值: 成功返回0

失败返回-1

7、accept

函数原型: int accept (int sockfd, struct sockaddr *addr, socklen_t *addrlen);

功能: 从监听的socket中提取连接请求,完成连接(三次握手)

返回已连接的一个新socket

参数: sockfd:监听的socket的fd

addr :用来存放,客户端的地址信息

addrlen : 值结果参数

返回值: 成功返回 已连接的socket的fd //专门用于后面通信的

失败-1

注意: addrlen必须初始化 ,初始成 addr对应sockaddr_in 类型的大小

8、tcp客户端

socket

connect

9、tcp服务器

socket

bind

listen

connfd = accept()

练习

1、客户端实现收发功能(配合网络调试助手完成)

#include "../head.h"

int main(int arg,char const *argv[]) //主函数传参
{
char tmp[256] = {"hello world"};

int fd = socket(AF_INET,SOCK_STREAM,0);
if (fd < 0)
{
perror("fail to socket");
return -1;
}
printf("fd = %d\n",fd);

struct sockaddr_in seraddr;
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(50000);
seraddr.sin_addr.s_addr = inet_addr("192.168.0.161");

if (connect(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0)
{
perror("fail to connect");
return -1;
}

while (1)
{
fgets(tmp,sizeof(tmp),stdin);
tmp[strlen(tmp)-1] = '\0';
if (0 == strcmp(tmp,".quit"))
{
break;
}
write(fd,tmp,strlen(tmp)+1);

}

close(fd);

return 0;
}

2、服务器实现实现收发功能(配合网络调试助手完成)

#include "../head.h"

int main(int argc,char const*argv[])
{
int fd = 0;

fd = socket(AF_INET,SOCK_STREAM,0);
if (fd < 0)
{
perror("fail to socket");
return -1;
}
printf("fd = %d\n",fd);
struct sockaddr_in seraddr;
bzero(&seraddr,sizeof(seraddr)); //初始化
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(50000);
seraddr.sin_addr.s_addr = inet_addr("192.168.0.162");
if (bind(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0)
{
perror("fail to bind");
return -1;
}

if (listen(fd,5) < 0)
{
perror("fail to listen");
return -1;
}
#if 0

int connfd = accept(fd,NULL,NULL);
if (connfd < 0 )
{
perror("fail to accept");
return -1;
}

write(connfd,"hello",6);
printf("----client connect---\n");
printf("-----连接成功-----\n");
#endif

struct sockaddr_in cliaddr;
bzero(&cliaddr,0);
socklen_t len = sizeof(cliaddr);
int connfd = accept(fd,(struct sockaddr *)&cliaddr,&len);
if (connfd < 0)
{
perror("accept fail");
return -1;
}

printf("----client connect---\n");
printf("client ip:%s\n",inet_ntoa(cliaddr.sin_addr));
printf("port :%d\n",ntohs(cliaddr.sin_port));

return 0;
}

相关推荐
007php00720 分钟前
Jenkins+docker 微服务实现自动化部署安装和部署过程
运维·数据库·git·docker·微服务·自动化·jenkins
路溪非溪42 分钟前
嵌入式Linux驱动开发杂项总结
linux·运维·驱动开发
2501_920047031 小时前
nginx-限速-限制并发连接数-限制请求数
运维·nginx
RainbowJie11 小时前
Gemini CLI 与 MCP 服务器:释放本地工具的强大潜力
java·服务器·spring boot·后端·python·单元测试·maven
蓝黑20201 小时前
VSCode远程连接阿里云ECS服务器
服务器·vscode·阿里云
网硕互联的小客服1 小时前
服务器支持IPv6吗?如何让服务器支持IPv6
运维·服务器·ip
励志五个月成为嵌入式糕手2 小时前
0825 http梳理作业
网络·网络协议·http
三无少女指南2 小时前
动态线程池核心解密:从 Nacos 到 Pub/Sub 架构的实现与对比
运维·架构
poison_Program3 小时前
使用 Prometheus 监控服务器节点:Node Exporter 详解与配置
运维·服务器·prometheus
张童瑶3 小时前
Linux 离线安装lrzsz(rz、sz上传下载小插件)
linux·运维·centos