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 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux网络编程2——socket编程 -> 正文阅读

[系统运维]Linux网络编程2——socket编程

学习视频链接

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

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

1.1 原理图

809b2c8ac5cb4e4f875f80d774c1f74a.png

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

1.2 简介

在通信过程中,套接字一定是成对出现的

二、网络字节序

2.1 大小端法

小端法:(pc本地存储) 高位存高地址。地位存低地址。int a = 0x12345678

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

计算机采用小端法

网络采用大端法

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 ——> 本地字节序?——> 网络字节序 (IP)

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

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

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

2、对上面函数进行封装

192.168.1.11 本质是一个 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 地址(点分十进制)

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,由地址族确定,然后函数内部再强制类型转化为所需的地址类型

97cac11203664c1fafd08d5391c81b2a.png

通过 man 7 ip 查看

4.2 新建一个sockaddr

struct sockaddr_in addr;

addr.sin_family = AF_INET/AF _INET6;? // 选择 ip 类型 ipv4、ipv6

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(选择报式协议套接字)

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 <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define SERV_PORT 9527

void sys_err(const char *str)
{
    perror(str);
    exit(1);
}

int main(int argc, char *argv[])
{
    int lfd = 0, cfd = 0;
    int ret;
    char buf[BUFSIZ];  // BUFSIZ 系统自带的宏,大小 4096

    struct 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");
    }

    while (1) {
        ret = read(cfd, buf, sizeof(buf));
        write(STDOUT_FILENO, buf, ret);

        for (int i = 0; i < ret; i++) {
            buf[i] = toupper(buf[i]);
        }

        write(cfd, buf, ret);  // 写回到客户端
    }
    close(lfd);
    close(cfd);

    return 0;
}

6.3 测试运行

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-05-18 18:01:16  更:2022-05-18 18:02:27 
 
开发: 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年11日历 -2024/11/15 16:27:04-

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