LinuxTCP编程详解

目录

一、创建套接字

二、绑定套接字

示例

三、监听套接字

四、等待套接字

五、服务器端示例

六、连接套接字

七、客户端示例

八、Send和Recv


C/S模式:Client客户端、Server服务器

TCP编程基于socket套接字实现,因此也习惯称为Socket编程

一、创建套接字

#include <sys/types.h>
#include <sys/socket.h>

//创建套接字
int socket(int doman, int type, int protocol)
    
params: domain:  AF_INET----IPV4
				 AF_INET6---IPV6
    			 AF_UNIX,AF_LOCAL--本地通信  
                 此外还有AF_NETLINK用于做设备驱动/内核用户间通信、AF_PACKET原始套接字
    	
        type:    SOCK_STREAM 流式套接字 唯一对应TCP
    			 SOCK_DGRAM  数据报套接字 唯一对应UDP
    			 SOCK_RAW    原始套接字 
    	protocol:一般填0
            
return:成功时返回fd,出错时返回-1

二、绑定套接字

#include <sys/types.h>
#include <sys/socket.h>

//绑定套接字----服务器使用
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
    
params:	addr:    //配置完sockaddr_in(见下)后---强转为sockaddr指针
    	addrlen: //

return:成功返回0,出错返回-1
            
//补充
struct sockaddr{ //通用结构体 仅作为一种模型,实际上要将下面的结构体配置完成后强转为此结构体
    sa_family_t sa_family;  //2B 协议族
    char        sa_data[14];//IP+端口号
}
struct sockaddr_in{	//基于Internet通信的结构体
    sa_family_t    sin_family;//2B AF_INET(IPV4)
    in_port_t      sin_port;  //2B 端口号
    struct in_addr sin_addr;  //4B IP地址
    unsigned char sin_zero[8]; //无实际意义 只是为了跟sockaddr大小对齐
}
struct in_addr{	//Internet地址---32位网络字节序
    uint32_t s_addr;
}   

IP地址转换补充:

#include <arpa/inet.h>

//将点分十进制形式IP地址的字符串 转换为32位网络字节序整数
//仅用于IPV4,出错时返回-1,因此不能转换全网广播255.255.255.255的地址
in_addr_t inet_addr(const char *cp) 


#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

//将点分十进制形式IP地址的字符串 转换为32位网络字节序整数
//IPV4和IPV6都可用,能正确处理全网广播的地址
int inet_pton(int af, const char *src, void *dst)
    
params: af----AF_INET或AF_INET6
    	src---源地址---点分十进制形式IP字符串
    	dst---转换结果地址---32位整数
    
return: 成功返回1 出错返回其他值
    
//和它反过来的,将32位整数转换为点分十进制形式IP地址字符串
//成功返回非空指针,失败返回NULL
const char *inet_ntop(int af, const void * src, char * dst, socklen_t size)   

示例

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h> //exit
#include <string.h> //bzero
#include <strings.h> //strncasecmp 忽略大小写比较
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define SERV_PORT (5001)
#define SERV_IP   "127.0.0.1"
#define BUFSIZE   (128)

int main(void)
{
    int sock_fd;
    struct sockaddr_in sin;

	//1.创建
    if( (sock_fd = socket(AF_INET,SOCK_STREAM,0)) == -1 )
    {
        perror("socket");
        exit(1);
    }
	//2.绑定 需要先配置sockaddr_in
    bzero(&sin,sizeof(sin));//清零再填充 
    sin.sin_family = AF_INET;//IPV4
    sin.sin_port   = htons(SERV_PORT);//端口号转换网络字节序
    //两种IP地址转换
    //sin.sin_addr.s_addr = inet_addr(SERV_IP);
    if( inet_pton(AF_INET,SERV_IP,(void*)&sin.sin_addr) != 1 ) 
    {
        perror("inet_pton");
        exit(1);
    }
    if(bind(sock_fd,(struct sockaddr*)&sin,sizeof(sin)) == -1)
    {
        perror("bind");
        exit(1);
    }

三、监听套接字

#include <sys/types.h>
#include <sys/socket.h>

//监听套接字,server端将主动套接字--->被动套接字
int listen(int sockfd, int backlog)

params: backlog 一般填5 指同时允许几路客户端和服务器进行正在连接(正在三次握手)ARM最大为8
    
return:成功返回0,出错返回-1 

内核中服务器的套接字fd会维护2个链表:

  • 正在三次握手的客户端链表(数量=2*backlog+1)

  • 已经建立好连接的客户端链表(已完成三次握手且分配好了newfd)

四、等待套接字

#include <sys/types.h>
#include <sys/socket.h>

//阻塞等待客户端连接
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
    
params: addr 	客户端信息的指针(用户传入,连接完成内核保存进去),不需要的话填NULL
		addrlen 客户端信息长度的指针,不需要的话填NULL
    
return: 成功返回已建立连接的新的客户端描述符newfd(非负整数)
    	出错返回-1

五、服务器端示例

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h> //exit
#include <string.h> //bzero
#include <strings.h> //strncasecmp 忽略大小写比较
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define SERV_PORT (5001)
#define SERV_IP   "127.0.0.1"
#define BUFSIZE   (128)
#define QUIT_STR  "quit"

int main(void)
{
    int sock_fd,newfd;
    struct sockaddr_in sin;
    char rd_buf[BUFSIZE];
    int read_num;

	//1.创建
    if( (sock_fd = socket(AF_INET,SOCK_STREAM,0)) == -1 )
    {
        perror("socket");
        exit(1);
    }
	//2.绑定 需要先配置sockaddr_in
    bzero(&sin,sizeof(sin));//清零再填充 
    sin.sin_family = AF_INET;//IPV4
    sin.sin_port   = htons(SERV_PORT);//端口号转换网络字节序
    //两种IP地址转换
    //sin.sin_addr.s_addr = inet_addr(SERV_IP);
    if( inet_pton(AF_INET,SERV_IP,(void*)&sin.sin_addr) != 1 ) 
    {
        perror("inet_pton");
        exit(1);
    }
    if(bind(sock_fd,(struct sockaddr*)&sin,sizeof(sin)) == -1)
    {
        perror("bind");
        exit(1);
    }
    //3.监听
    if( listen(sock_fd,5) == -1 )
    {
        perror("listen");
        exit(1);
    }
    //4.阻塞等待客户端连接 连接成功后需要newfd
    if( (newfd = accept(sock_fd,NULL,NULL)) == -1 )
    {
        perror("accept");
        exit(1);
    }
	while(1)
    {
        bzero(rd_buf,BUFSIZE); //读之前先请零
        do
        {
            read_num = read(newfd,rd_buf,BUFSIZE-1);
        }while(read_num < 0 && errno == EINTR);
        if(read_num < 0)
        {
            perror("read");
        }
        if(read_num == 0) //客户端关闭
        {
            printf("Client is closed!\n");
            break;
        }
        printf("Server received:%s\n",rd_buf);
        if( strncasecmp(rd_buf,QUIT_STR,strlen(rd_buf)) == 0)//客户端输入quit
        {
            printf("Client is exiting!\n");
            break;
        }
    }
    close(newfd);.	
    close(sock_fd);

    return 0;
}

六、连接套接字

#include <sys/types.h>
#include <sys/socket.h>

//连接服务器创建的套接字----客户端用
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
    
params: //参数同bind----表示配置方式相近   
    
return: 成功返回0,出错返回-1

七、客户端示例

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h> //exit
#include <string.h> //bzero
#include <strings.h> //strncasecmp 忽略大小写比较
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define SERV_PORT (5001)
#define SERV_IP   "127.0.0.1" //只能用ifconfig查到的
#define BUFSIZE   (128)
#define QUIT_STR  "quit"

int main(void)
{
    int sock_fd;
    struct sockaddr_in cin;
    char wr_buf[BUFSIZE];

    //1.创建
    sock_fd = socket(AF_INET,SOCK_STREAM,0);
    if(sock_fd == -1)
    {
        perror("socket");
        exit(1);
    }
    //2.连接服务器,还是一样先配置sockaddr_in
    bzero(&cin,sizeof(cin));
    cin.sin_family = AF_INET;
    cin.sin_port   = htons(SERV_PORT);
    //cin.cin_addr.s_addr = inet_addr(SERV_IP); 
    if( inet_pton(AF_INET,SERV_IP,(void*)&cin.sin_addr) != 1 )
    {
        perror("inet_pton");
        exit(1);
    }
    if( connect(sock_fd,(struct sockaddr*)&cin,sizeof(cin)) == -1 )
    {
        perror("connect");
        exit(1);
    }

    //3.写数据
    while(1)
    {
        bzero(wr_buf,BUFSIZE);//写之前先清零
        if( fgets(wr_buf,BUFSIZE-1,stdin) == NULL)
        {
            continue;//重新获取
        }
        write(sock_fd,wr_buf,strlen(wr_buf));//写数据--相当于发送给服务器

        if( strncasecmp(wr_buf,QUIT_STR,strlen(QUIT_STR)) == 0) //输入了quit
        {
            break;
        } 
    }

    close(sock_fd);
    return 0;
}

八、Send和Recv

1.网络发送数据

#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags)
    
params: 前三个参数同write
    	flags	一般填0---此时同write
    			MSG_DONTWAIT 非阻塞版本
    			MSG_OOB 用于发送TCP类型的带外数据(out-of-band)

2.网络接收数据

#include <sys/types.h>
#include <sys/socket.h>

ssize_t read(int sockfd, const void *buf, size_t len, int flags)
    
params: 前三个参数同read
    	flags	一般填0---此时同read
    			MSG_DONTWAIT 非阻塞版本
    			MSG_OOB 用于发送TCP类型的带外数据(out-of-band)
    			MSG_PEEK 偷看数据,读完不清除,非常实用
    
return: 成功返回收到字节数,失败返回-1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/929222.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入解析级联操作与SQL完整性约束异常的解决方法

目录 前言1. 外键约束与级联操作概述1.1 什么是外键约束1.2 级联操作的实际应用场景 2. 错误分析&#xff1a;SQLIntegrityConstraintViolationException2.1 错误场景描述2.2 触发错误的根本原因 3. 解决方法及优化建议3.1 数据库级别的解决方案3.2 应用层的解决方案 4. 友好提…

「Mac畅玩鸿蒙与硬件41」UI互动应用篇18 - 多滑块联动控制器

本篇将带你实现一个多滑块联动的控制器应用。用户可以通过拖动多个滑块&#xff0c;动态控制不同参数&#xff08;如红绿蓝三色值&#xff09;&#xff0c;并实时显示最终结果。我们将以动态颜色调节为例&#xff0c;展示如何结合状态管理和交互逻辑&#xff0c;打造一个高级的…

数字IC前端学习笔记:脉动阵列的设计方法学(以串行FIR滤波器为例)

相关阅读数字IC前端_日晨难再的博客-CSDN博客https://blog.csdn.net/weixin_45791458/category_12173698.html?spm1001.2014.3001.5482 引言 脉动结构&#xff08;也称为脉动阵列&#xff09;表示一种有节奏地计算并通过系统传输数据的处理单元(PEs)网络。这些处理单元有规律地…

图片预处理技术介绍4——降噪

图片预处理 大家好&#xff0c;我是阿赵。   这一篇将两种基础的降噪算法。   之前介绍过均值模糊和高斯模糊。如果从降噪的角度来说&#xff0c;模糊算法也算是降噪的一类&#xff0c;所以之前介绍的两种模糊可以称呼为均值降噪和高斯降噪。不过模糊算法对原来的图像特征的…

【数据中心建设资料】数据中心安全建设解决方案,数据中心整理解决方案,数据中心如何做到安全保障,数据中台全方案(Word全原件)

第一章 解决方案 1.1 建设需求 1.2 建设思路 1.3 总体方案 信息安全系统整体部署架构图 1.3.1 IP准入控制系统 1.3.2 防泄密技术的选择 1.3.3 主机账号生命周期管理系统 1.3.4 数据库账号生命周期管理系统 1.3.5 双因素认证系统 1.3.6 数据库审计系统 1.3.7 数据脱敏系统 1.3.8…

十,[极客大挑战 2019]Secret File1

点击进入靶场 查看源代码 有个显眼的紫色文件夹&#xff0c;点击 点击secret看看 既然这样&#xff0c;那就回去查看源代码吧 好像没什么用 抓个包 得到一个文件名 404 如果包含"../"、"tp"、"input"或"data"&#xff0c;则输出"…

UE5 C++ 不规则按钮识别,复选框不规则识别 UPIrregularWidgets

插件名称&#xff1a;UPIrregularWidgets 插件包含以下功能 你可以点击任何图片&#xff0c;而不仅限于矩形图片。 UPButton、UPCheckbox 基于原始的 Button、Checkbox 扩展。 复选框增加了不规则图像识别功能&#xff0c;复选框增加了悬停事件。 欢迎来到我的博客 记录学习过…

【数据结构】手搓链表

一、定义 typedef struct node_s {int _data;struct node_s *_next; } node_t;typedef struct list_s {node_t *_head;node_t *_tail; } list_t;节点结构体&#xff08;node_s&#xff09;&#xff1a; int _data;存储节点中的数据struct node_s *_next;&#xff1a;指向 node…

【Win11的Bug】无法在文件夹中创建txt文件

问题 右键只能新建文件夹 , 无法新建txt文本文档 解决办法 将注册表中的一个参数从1改为0即可. 具体内容: WinR输入regeditHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System 将1改为0(下面这张图我已改过) 4.然后重新启动电脑即可 小技…

基于Matlab三点雨流计数法的载荷时间历程分析与循环疲劳评估

随着工程领域中机械设备和结构系统的复杂性不断增加&#xff0c;疲劳分析成为评估其可靠性与使用寿命的关键环节。载荷时间历程数据在疲劳分析中扮演着重要角色&#xff0c;而雨流计数法作为经典的循环计数方法&#xff0c;能够有效地从载荷时间历程中提取疲劳载荷循环信息。本…

二、部署docker

二、安装与部署 2.1 安装环境概述 Docker划分为CE和EE&#xff0c;CE为社区版&#xff08;免费&#xff0c;支持周期三个月&#xff09;&#xff0c;EE为企业版&#xff08;强调安全&#xff0c;付费使用&#xff09;。 Docker CE每月发布一个Edge版本&#xff08;17.03&…

python + PPT

ppt转化为word 对于PPT中的文本内容&#xff0c;如何转化为word内容呢&#xff1f;下面的代码可以实现如下功能 代码如下&#xff1a; from pptx import Presentation from docx import Documentdef clean_text(text):"""清理文本&#xff0c;移除控制字符&quo…

linux运维命令

防火墙相关命令 防火墙规则查看 firewall-cmd --list-all 禁ping firewall-cmd --permanent --add-rich-rulerule protocol valueicmp drop firewall-cmd --reload 执行完以上命令后&#xff0c;通过firewall-cmd --list-all查看规则生效情况 firewall-cmd --list-all 其…

论文笔记:Asymptotic Midpoint Mixup for Margin Balancing and Moderate Broadening

1. Motivation 在特征空间中&#xff0c;特征之间的collapse会导致representation learning 中的关键问题&#xff0c;这是因为特征之间不可区分。基于线性插值的增强方法&#xff08;例如 mixup&#xff09;已经显示出它们在缓解类间塌陷&#xff08;称为inter-class collaps…

Elasticsearch之索引的增删改查(6.x版本)-yellowcong

1. 节点信息查看 #查看集群健康情况 curl -X GET localhost:9200/_cat/health?v&pretty#查看节点信息 curl -X GET localhost:9200/_cat/nodes?v&pretty 2. 索引管理 在es中&#xff0c;索引就相当于是mysql中的库了。 #查看索引列表 curl -X GET localhost:9200/…

Linux红帽认证有哪些等级?RHCE含金量如何?

工 仲 好&#xff1a;IT运维大本营哈喽&#xff0c;大家好&#xff01; 红帽认证&#xff0c;作为一个备受瞩目的认证体系&#xff0c;其完善程度在行业内有口皆碑。 它清晰地划分为三个等级&#xff0c;分别是初级、中级和高级&#xff0c;每个等级都具有独特的要求和价值。…

ArcGIS求取多个点距离线要素的最近距离以及距离倒数

本文介绍在ArcMap软件中&#xff0c;对于点要素中的每一个点&#xff0c;求取其距离最近的道路的距离、距离倒数的方法。 首先&#xff0c;看一下本文的需求。现在已知一个点要素&#xff0c;其中含有多个点&#xff0c;假设每一个点表示城市中的一家商店&#xff1b;同时&…

大数据实验E5HBase:安装配置,shell 命令和Java API使用

实验目的 熟悉HBase操作常用的shell 命令和Java API使用&#xff1b; 实验要求 掌握HBase的基本操作命令和函数接口的使用&#xff1b; 实验平台 操作系统&#xff1a;Linux&#xff08;建议Ubuntu16.04或者CentOS 7 以上&#xff09;&#xff1b;Hadoop版本&#xff1a;3…

跑一下pyapp

文档&#xff1a;How-to - PyApp 首先没有rust要安装 安装 Rust - Rust 程序设计语言 查看是否安装成功 然后clone下pyapp https://github.com/ofek/pyapp/releases/latest/download/source.zip -OutFile pyapp-source.zip 进入目录中&#xff0c;cmd&#xff0c;设置环境…

Python_Flask01

所有人都不许学Java了&#xff0c;都来学Python&#xff01; 如果不来学的话请网爆我的老师---蔡老师 Flask的前世姻缘 我不知道&#xff0c;没啥用&#xff0c;要学好这个框架&#xff0c;其实多读书&#xff0c;多看报就行了&#xff0c;真心想了解的话&#xff01; Welcom…