网络编程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_INETAF_INET6
  • typ:数据传输方式
    • 常用SOCK_STREAMSOCK_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 tmp256 = {"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);
tmpstrlen(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;
}

相关推荐
zzzzzz31015 小时前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
XIAOHEZIcode16 小时前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220701 天前
如何搭建本地yum源(上)
运维
大树884 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠4 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质4 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
小宇宙Zz4 天前
Maven依赖冲突
java·服务器·maven
Inhand陈工4 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
网络研究院4 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展
酣大智4 天前
ARP代理--工作原理
运维·网络·arp·arp代理