学习视频链接

黑马程序员-Linux网络编程_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1iJ411S7UA?p=17

目录

一、网络套接字(英文socket)

1.1 原理图

1.2 简介

二、网络字节序

2.1 大小端法

2.2 函数介绍

三、IP地址转换函数

3.1 inet_pton

3.2 inet_ntop

四、sockaddr 数据结构

4.1 简介

4.2 新建一个sockaddr

五、socket流程和相关函数

5.1 流程图

5.2 socket函数

5.3 bind函数

5.4 listen函数

5.5 accept函数

5.6 connect函数

六、server的实现

6.1 建立C语言项目

6.2 代码

6.3 测试运行

七、client 客户端的实现

7.1 代码

7.2 测试

八、错误处理函数封装

8.1 思路

8.2 测试代码(代码优点问题,后面再修改)


一、网络套接字(英文socket)

1.1 原理图

虚线方框表示的是一个套接字

1.2 简介

类似于管道文件。一个文件描述符指向一个套接字(套接字内部由内核提供两个缓冲区实现)

在通信过程中,套接字一定是成对出现的(Linux主机上有,客户端主机上也有)

二、网络字节序

2.1 大小端法

小端法:(pc本地存储) 高位存高地址。地位存低地址

大端法:(网络存储) 高位存低地址。地位存高地址

计算机采用小端法

网络采用大端法

因为小端法在计算机网络传播中要一直被路由解码,很麻烦,所以计算机上使用小端法存储的数据要转换成大端法的数据,再发送到网络上

小端字节序不太清楚是什么,可以看我在知乎上面记的笔记

《x86汇编语言》第2章 让计算机执行处理器指令 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/521534699

2.2 函数介绍

1、函数

为使网络程序具有可移植性,使同样的 C 代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和本地字节序的转换

#include <arpa/inet.h>uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

htonl:本地字节序 ——> 网络字节序 (32 位,主要转换的是 IP)

htons:本地字节序 ——> 网络字节序 (16 位,主要转换的是 port)

ntohl:网络字节序 ——> 本地字节序 (IP)

ntohs:网络字节序 ——> 本地字节序 (port)

2、对上面函数进行封装

192.168.1.11 本质是一个 string,通过 atoi 把这 string 转换成 int 整数,再调用 htonl 转换成网络字节序的整个流程可以用下面的函数代替

#include <arpa/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);

该函数支持 IPv4 和 IPv6

三、IP地址转换函数

3.1 inet_pton

1、作用

本地字节序 (string IP) ——> 网路字节序(二进制)

2、int inet_pton(int af, const char *src, void *dst);

(1) 参数

af:AF_INET、AF_INET6

src:传入参数,IP 地址(点分十进制:192.168.10.100)

dst:传出参数,转换后的网络字节序的 IP 地址

(2) 返回值:

成功:1

异常:0,说明 src 指向的不是一个有效的 ip 地址

失败:-1

3.2 inet_ntop

1、作用

网络字节序(二进制)——> 本地字节序 (string IP)

2、const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

(1) 传入参数

af:AF_INET、AF_INET6

src:传入参数,网络字节序 IP 地址

dst:传出参数,本地字节序 (string IP)

size:传出参数,dst 的大小

(2) 返回值

成功:dst

失败:NULL

四、sockaddr 数据结构

4.1 简介

strcut sockaddr 很多网络编程函数诞生早于 IPv4 协议,那时候都使用的是 sockaddr 结构体,为了向前兼容,现在 sockaddr 退化成了 (void*) 的作用,传递一个地址给函数,至于这个函数是sockaddr_in 还是 sockaddr_in6,由地址族确定,然后函数内部再强制类型转化为所需的地址类型

通过 man 7 ip 查看

4.2 新建一个sockaddr

struct sockaddr_in addr;

addr.sin_family = AF_INET/AF _INET6;  // 选择 ip 类型 ipv4、ipv6、man 7 ip 查看开发者手册

addr.sin_port = htons(9527);  // 选择端口号

// 写法1:选择 ip 地址

int dst;

inet_pton(AF_INET, "192.157.22.45", (void*)&dst);

addr.sin_addr.s_addr = dst;

// 写法2:选择 ip 地址

addr.sin_addr.s_addr = htonl(INADDR_ ANY);   // 取出系统中有效的任意IP地址,二进制类型(可以转换成字节序)

bind(fd, (struct sockaddr *)&addr, size);

五、socket流程和相关函数

5.1 流程图

server:

1、socket()  创建socket
2、bind() 绑定服务器地址结构
3、listen() 监听上限
4、accept() 阻塞监听客户端连接
5、read() 读socket获取客户端数据
6、小写—>大写 toupper()
7、write(fd)
8、close()

client:

1、socket() 创建socket
2、connect() 与服务器建立连接
3、write() 写数据到socket
4、read() 读转换后的数据
5、显示读取结果
6、close()

5.2 socket函数

1、作用

创建一个套接字

2、#include <sys/socket.h>

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

(1) 参数

domain:AF_INET、AF_INET6、AF_UNIX(ip地址协议:ipv4、ipv6、本地套接字)

type:SOCK_STREAM、SOCK_DGRAM(数据传输协议:流式协议、报式协议)

protocol:0(选择流式协议或报式协议的代表协议,流式协议的代表协议为TCP,报式协议的代表协议为UDP)

SOCK_STREAM与SOCK_DGRAM套接字 - 简书 (jianshu.com)https://www.jianshu.com/p/046f37121259

(2) 返回值

成功:新套接字所对应文件描述符

失败:-1 errno

5.3 bind函数

1、作用

给 socket 绑定一个地址结构 (IP +port)

2、#include <sys/socket.h>

#include <arpa/inet.h>

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

(1) 参数

sockfd:socket 函数返回值

addr.sin_family = AF_INET;

addr.sin_port = htons(8888);

addr.sin_addr.s_addr = htonl(INADDR_ANY);

addr:传入参数(struct sockaddr *)&addr

addrlen:sizeof(addr) 地址结构的大小

(2) 返回值

成功:0

失败:-1 errno

5.4 listen函数

1、作用

设置同时与服务器建立连接的上限数 (同时进行 3 次握手的客户端数量)

2、int listen(int sockfd, int backlog);

(1) 参数

sockfd:socket 函数返回值

backlog:上限数值。最大值 128

(2) 返回值:

成功:0

失败:-1 errno

5.5 accept函数

1、作用

阻塞等待客户端建立连接,成功的话,返回一个与客户端成功连接的 socket 文件描述符

2、int accept(int sockfd, struct sockaddr *addr,socklen_t *addrlen);

(1) 参数

sockfd:socket 函数返回值

addr:传出参数。成功与服务器建立连接的那个客户端的地址结构 (IP + port)

socklen_t clit_addr_len = sizeof(addr);

addrlen:传入传出。&clit_addr_len  入:addr 的大小。 出:客户端 addr 实际大小

(2) 返回值

成功:能与服务器进行数据通信的 socket 对应的文件描述

失败:-1  errno

5.6 connect函数

1、作用

使用现有的 socket 与服务器建立连接

2、int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

(1) 参数

sockfd:socket 函数返回值

addr:传入参数。服务器的地址结构

(2) 返回值:

成功:0

失败:-1 errno

如果不适用 bind 绑定客户端地址结构,采用 "隐式绑定"

六、server的实现

6.1 建立C语言项目

6.2 代码

#include <stdio.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>#define SERV_PORT 9527void sys_err(const char *str)
{perror(str);exit(1);
}int main(void)
{int lfd = 0, cfd = 0;int ret, i;char buf[BUFSIZ], client_IP[1024];  // BUFSIZ 系统自带的宏,大小 4096struct sockaddr_in serv_addr, clit_addr;socklen_t clit_addr_len;serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(SERV_PORT);serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);// AF_INET:     ipv4// SOCK_STREAM: 提供面向连接的稳定数据传输,即TCP协议lfd = socket(AF_INET, SOCK_STREAM, 0);if (lfd == -1) {sys_err("socket error");}// 给socket绑定地址bind(lfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));// 最大连接数listen(lfd, 128);clit_addr_len = sizeof(clit_addr);cfd = accept(lfd, (struct sockaddr *)&clit_addr, &clit_addr_len);if (cfd == -1) {sys_err("accept error");}printf("client ip:%s port:%d\n",inet_ntop(AF_INET, &clit_addr.sin_addr.s_addr, client_IP, sizeof(client_IP)),ntohs(clit_addr.sin_port));while (1) {ret = read(cfd, buf, sizeof(buf));write(STDOUT_FILENO, buf, ret);for (i = 0; i < ret; i++) {buf[i] = toupper(buf[i]);}write(cfd, buf, ret);  // 写回到客户端}close(lfd);close(cfd);return 0;
}

6.3 测试运行

七、client 客户端的实现

7.1 代码

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/socket.h>#define SERV_PORT 9527void sys_err(const char *str)
{perror(str);exit(1);
}int main(void)
{int cfd;int conter = 10;char buf[BUFSIZ];struct sockaddr_in serv_addr;  // 服务器地址结构serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(SERV_PORT);inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr.s_addr);cfd = socket(AF_INET, SOCK_STREAM, 0);if (cfd == -1) {sys_err("socket error");}int ret = connect(cfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));if (ret != 0) {sys_err("connect error");}while (--conter) {write(cfd, "hello\n", 6);ret = read(cfd, buf, sizeof(buf));write(STDOUT_FILENO, buf, ret);sleep(1);}close(cfd);return 0;
}

7.2 测试

八、错误处理函数封装

8.1 思路

写一个函数来代替原来的函数,这个函数拥有原来的函数的功能,并且出错以后会检测到

8.2 测试代码(代码有点错误,会意即可)

Linux网络编程2——socket编程相关推荐

  1. linux网络编程之socket编程(六)

    经过一个国庆长假,又有一段时间没有写博文了,今天继续对linux网络编程进行学习,如今的北京又全面进入雾霾天气了,让我突然想到了一句名句:"真爱生活,珍惜生命",好了,言归正传. ...

  2. linux网络编程之Socket编程

    (1)socket套接字 1)在linux环境下,socket用于表示进程间网络通信的特殊文件类型,其本质是内核借助缓冲区形成的伪文件(不占磁盘空间,除此之外还有二进制文件,管道,字符文件). 2)伪 ...

  3. 【socket】从计算机网络基础到socket编程——Windows Linux C语言 + Python实现(TCP+UDP)

    一.部分基础知识 1.1 计算机网络的体系结构 1.11 互联网简介 1.12 计算机网络的分类 1.13 协议与网络的分层体系结构 ▶ 协议 ▶ 网络的分层体系结构 1.14 OSI 七层模型(重要 ...

  4. (转)网络编程:Socket编程从IPv4转向IPv6支持

    目前运行主流的IT系统中,用于解决分布式系统内部模块及不同的系统间通信的一种主要的解决方案就是使用套接字Socket来开发应用.由于当前大部分正在运行的IT系统中使用套接字Socket开发环境基本上都 ...

  5. linux下的c socket编程(4)--server端的继续研究

    linux下的C socket编程(4) 延长server的生命周期: 在前面的一个个例子中,server在处理完一个链接之后便会立即结束掉自己,然而这种server并不科学,server因该使能够一 ...

  6. 网络协议 11 - Socket 编程(下):眼见为实耳听为虚

    网络协议 11 - Socket 编程(下):眼见为实耳听为虚 原文:网络协议 11 - Socket 编程(下):眼见为实耳听为虚 系列文章传送门: 网络协议 1 - 概述 网络协议 2 - IP ...

  7. linux网络编程、socket编程

    进程间通信: 特点:依赖于内核,造成缺陷--无法实现多机通信. 网络: 地址:由IP地址(IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物 ...

  8. Linux 系统应用编程——网络编程(socket编程)

    二.网络编程基础 1.套接字概述 套接字就是网络编程的ID.网络通信,归根到底还是进程间的通信(不同计算机上的进程间的通信).在网络中,每一个节点(计算机或路由器)都有一个网络地址,也就是IP地址,两 ...

  9. 1.socket编程:socket编程,网络字节序,函数介绍,IP地址转换函数,sockaddr数据结构,网络套接字函数,socket相关函数,TCP server和client

     1  Socket编程 socket这个词可以表示很多概念: 在TCP/IP协议中,"IP地址+TCP或UDP端口号"唯一标识网络通讯中的一个进程,"IP 地址+端 ...

最新文章

  1. oracle自动备份
  2. 【原创】WP7.8 ROM更新图文并茂
  3. 关于临时表和表变量的差别1
  4. Linux目录结构FHS
  5. 四年级下册英语计算机房和教师办公室的图片,PEP英语四年级下册-Unit-1思维导图及知识点梳理.pptx...
  6. 在线实时大数据平台Storm开发之wordcount
  7. C++实用技巧(二)
  8. NYOJ-99 单词拼接(欧拉+回溯)
  9. rabbitmq启动失败-报Failed to load advanced configuration file解决方法
  10. PHPCMS的产品筛选功能
  11. c# MODBUS协议 上位机 (转载)
  12. 为什么开源和企业用户是天生的盟友
  13. 暑假周进度总结报告5
  14. 《二》Android 数据库 SQlite SQLiteOpenHelper
  15. Access数据库迁移到MS SQL Server数据库
  16. linux设置伪静态地址,wordpress网站linux和win主机URL伪静态设置方法详解
  17. r型聚类分析matlab实现,浅谈Matlab中的聚类分析 Matlab聚类程序的设计
  18. 语音识别之——mfcc什么是汉明窗,为什么加汉明窗
  19. 软件测试工具大全(这可能是目前为止最全的测试工具集合)
  20. 【批处理DOS-CMD命令-汇总和小结】-注册表编辑命令reg,如何用cmd命令打开注册表编辑器regedit

热门文章

  1. 职业经理人生涯规划设计实务
  2. Python+ChatGPT制作一个AI实用百宝箱
  3. python cookies是什么_Python中的Cookie模块有什么功能?
  4. ubuntu选择桌面环境_选择您的Ubuntu:8种具有不同桌面环境的Ubuntu衍生物
  5. 计算机考试为什么试题不能复制,3月ACCA考试开场——ACCA机考复制粘贴究竟可不可以?...
  6. php already loaded,php.ini 位置和重安 Xdebug 还有消除 Cannot load Xdebug - it was already loaded 信息的方法...
  7. BLE LL的SN和NESN
  8. Redis 对象的数据结构原理 - SDS、Inset、Dict、ZipList、QuickList、SkipList、RedisObject
  9. Win10与Ubuntu双系统下安装tensorflow2.0全流程备忘录
  10. 大学期末考java编程题_(完整版)大学期末考试Java题库