TCP编程

1.socket函数

int socket(int domain, int type, int protocol);
头文件:include<sys/types.h>,include<sys/socket.h>
参数
 int domain
AF_INET: IPv4 Internet protocols
 AF_INET6: IPv6 Internet protocols
 AF_UNIX, AF_LOCAL : Local communication

  •  AF NETLINK:kernel user interface device
  •  AF_PACKET: low level packer interface

 type

  •  SOCK_STREAM:流式接字 唯一对应TCP
  •  SOCK_DGRAM:数据包套接字,唯一对应UDP
  •  SOCK_RAM :原始套接字

 protocol:
        一般填0,原始套接字编程时需填充
返回值: 成功返回文件描述符,出错返回-1                                                                     

socket函数对应于普通文件的打开操作。普通文件的打开操作返回一个文件描述字,而socket()用于创建 一个socket描述符 (socket descriptor),它唯一标识一个socket。这个socket描述字跟文件描述字一样,后续的操作都 有用到它,把它作为参 数,通过它来进行一些读写操作。创建socket的时候,也可以指定不同的参数创建不同的socket描述 符,socket函数的三个参数 分别为: domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET、AF_INET6、 AF_LOCAL(或称AF_UNIX, Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址, 如AF_INET决定了 要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。 type:指定socket类型。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、 SOCK_PACKET、 SOCK_SEQPACKET等等(socket的类型有哪些?)。 protocol:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、 IPPROTO_SCTP、 IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议,type 和protocol并不 是可以随意组合的,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当protocol为0时,会自动选择 type类型对应的默 认协议。 

2.bind绑定函数

int bind(
        int sockfd, 
        struct sockaddr *my_addr, 
        int addrlen

        );
参数:
sockfd:通过socket()函数拿到的fd
addr:采用 struct socket的结构体地址
struct sockaddr (        //通用结构体
unsigned short sa_family; // 2个字
char sa_data[14];        // 14字节的协议地址
);
struct socket_in{        //基于socket通信结构体
sa family t sin family://两个字节
in_port_t sin_port;        //两个字节
struct in_addr sin_addr;// 四个字节\
sin zero[8];//八位,填充字节,需清零
}
struct in_addr(
uint32_ts_addr;        //32位网络字节序

}

addrlen:地址长度
返回值:
成功返回0

出错返回-1

当我们调用socket创建一个socket时,返回的socket描述字它存在于协议族(address family, AF_XXX)空间中,但没有一个 具体的地址。如果想要给它赋值一个地址,就必须调用bind()函数。通常服务器在启动的时候都会绑定 一个众所周知的地址(如 ip地址+端口号),用于提供服务,客户就可以通过它来接连服务器;而客户端就不用指定,由系统自动 分配一个端口号和自身 的ip地址组合。这就是为什么通常服务器端在listen之前会调用bind(),而客户端就不会调用,而是在 connect()时由系统随机生 成一个。当然客户端也可以在调用connect()之前bind一个地址和端口,这样就能使用特定的IP和端口来 连服务器了。

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

函数的三个参数分别为:

sockfd:即socket描述字,它是通过socket()函数创建了,唯一标识一个socket。bind()函数就是将给这 个描述字绑定一 个名字。

addrlen:对应的是地址的长度。

addr:一个const struct sockaddr *指针,指向要绑定给sockfd的协议地址。

这个地址结构根据地址创 建socket时的地 址协议族的不同而不同,但最终都会强制转换后赋值给sockaddr这种类型的指针传给内核:

通用套接字 sockaddr 类型定义:

ipv4对应的是sockaddr_in类型定义:

ipv6对应的sockaddr_in6类型定义:

网络字节序和主机字节序

主机字节序就是我们平常说的大端和小端模式:不同的CPU有不同的字节序类型,这些字节序是指整数 在内存中保存的顺序,

主机字节序就是我们平常说的大端和小端模式:不同的CPU有不同的字节序类型,这些字节序是指整数 在内存中保存的顺序, 这个叫做主机序。引用标准的Big-Endian和Little-Endian的定义如下: a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。 b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

网络字节序:4个字节的32 bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit, 最后是24~31bit。这 种传输次序称作大端字节序。由于TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序, 因此它又称作网络字节 序。字节序,顾名思义字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序,一个字节的数 据没有顺序的问题了。 所以: 在将一个地址绑定到socket的时候,请先将主机字节序转换成为网络字节序,再赋给socket。

serv_addr.sin_port = htons(LISTEN_PORT);

serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

这里通过调用两个函数 htons() 和 htolnl() 分别用来将 端口和IP地址转换成网络字节序,这两个函数名 中的 h表示host, n表 示network, s表示short(2字节/16位), l表示long(4字节/32位)。因为端口号是16位的,所以我们用 htons()把端口号从主机字节 序转换成网络字节序, 而IP地址是32位的,所以我们用htonl()函数把IP地址从主机字节序转换成网络字 节序。INADDR_ANY 就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。 一般来说,在各个系统中均 定义成为0值。这里也就意味着监听所有的IP地址。

3.listen()函数

int listen(int sockfd, int backlog);
 参数:
sockfd:通过socket()函数拿到的fd;
backLog:同时允许几路客户端和服务器进行正在连接的过程(正在三次握手),一般填5。
内核中服务器的套接字fd会维护2个链表
1.正在三次握手的客户端链表(数量=2*backlog+1)
2.已经建立好连接的客户端链表(已经完成三次握手分配好了的newfd)
返回值:
 成功返回0
 出错返回-1
listen(fd, 5);//表示系统允许11 (2*5+1)个客户端同时进行三次握手

4.accept()函数

阻塞等待客户端连接请求
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数
sockfd:经过前面socket()创建并通过bind(),listen()设置过的fd
addr:指向存放地址信息的结构体的首地址(获取客户端IP地址和端口号)
addrlen:存放地址信息的结构体的大小
返回值
成功,返回返回已经建立连接的新的newfd
出错, 返回-1

服务器代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include<sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#define QUIT_STR "QUIT”
#define BUFSIZE 1024
#define BACKLOG 5
#define SERV_IP 5001
#define SERV IP ADDR "192.168.182.144"
int main()
{int fd = -1;struct sockaddr_in sin;//1.socketfd = socket(AF_INET, SOCK_STREAM, 0);if(fd <0){perror(“socket");exit(1);}bzero(&sin, sizeof(sin));sin.sin family = AF_INET;sin.sin port = htons(SERV IP);sin.sin addr.s addr = inet addr(SERV IP ADDR);/*if(inet_pton(AF_INET, SERV_IP_ADDR,(votd *)&stn.sin_addr.s_addr) != 1)perror("inet_pton");exit(1);*///2.bindif(bind(fd, (struct sockaddr *)&sin, sizeof(sin)) <0){perror("bind");exit(1)}//3.listenif(listen(fd, BACKLOG) <0){perror("Listen");exit(1);}//4.acceptint newfd = -1;newfd = accept(fd, NULL, NULL);if(newfd <0){perror("accept");exit(1);}char buf[BUFSIZE];int ret = -1;//readwhile(1){do{bzero(buf, BUFSIZE);ret = read(newfd, buf, BUFSIZE-1);}while(ret <1);if(ret <0){exit(1);}if(!ret){break;}printf("receive data:%s\n", buf);if(!strncasecmp(buf, QUIT_STR, strlen(QUIT_STR))){printf("Client is exiting!\n");break;}}
close(newfd);
close(fd);
return 0;

5.客户端连接函数connect()

int connect (int[sockfd, struct sockaddr * serv_addr, int addrlen)
参数:
sockfd:通过socket()函数拿到的fd
addr:struct sockaddr的结构体变量地址
addrlen:地址长度
返回值:
 成功,返回0
 失败,返回-1

客户端代码

#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define QUIT_STR "QUIT"
#define BUFSIZE 1024
#define SERV_PORT 5001
#define SERV_IP_ADDR "192.168.182.144”
int main()
{int fd = -1;struct sockaddr_in sin;fd = socket(AF_INET, SOCK_STREAM, Gif(fd <0){perror("socket");exit(1);}bzero(&sin,sizeof(sin));sin.sin family = AF_INET;sin.sin port = htons(SERV_PORT);sin.sin_addr.s _addr= inet_addr(SERV_IP_ADDR);if(connect(fd, (struct sockaddr*)&sin, sizeof(sin))<0){perror("connect");exit(1);}char buf[BUFSIZE];while(1){bzero(buf, BUFSIZE);if(fgets(buf, BUFSIZE-1, stdin) == NULL){continue;}write(fd, buf, strlen(buf));if(!strncasecmp(buf, QUIT_STR, strlen(QUIT_STR))){break;}return 0;
}

TCP服务获取客户端IP地址

​#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include<sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#define QUIT_STR "QUIT”
#define BUFSIZE 1024
#define BACKLOG 5
#define SERV_IP 5001
#define SERV IP ADDR "192.168.182.144"
int main()
{int fd = -1;struct sockaddr_in sin;//1.socketfd = socket(AF_INET, SOCK_STREAM, 0);if(fd <0){perror(“socket");exit(1);}bzero(&sin, sizeof(sin));// sin.sin family = AF_INET;sin.sin port = htons(SERV IP);//sin.sin addr.s addr = inet addr(SERV IP ADDR);sin.sin addr.s addr =ADDR_ANY;/*if(inet_pton(AF_INET, SERV_IP_ADDR,(votd *)&stn.sin_addr.s_addr) != 1)perror("inet_pton");exit(1);*///2.bindif(bind(fd, (struct sockaddr *)&sin, sizeof(sin)) <0){perror("bind");exit(1);}//3.listenif(listen(fd, BACKLOG) <0){perror("Listen");exit(1);}//4.accept/*int newfd = -1;newfd = accept(fd, NULL, NULL);if(newfd <0){perror("accept");exit(1);}*/int newfd = -1;struct sockaddr _in cin;socklen_t addrlen = sizeof(cin);newfd = accept(fd, (struct sockaddr *)&cin, &addrlen);if(newfd <0){perror("accept");exit(1);}char ipv4_addr[16];if(!inet_ntop(AF_INET, (void *)&cin.sin _addr, ipv4_addr, sizeof(cin))){perror("inet_ntop");exit(1);}printf("Clint:(%s, %d)is connect!\n", ipv4 addr, ntohs(cin.sin_port));char buf[BUFSIZE];int ret = -1;//readwhile(1){do{bzero(buf, BUFSIZE);ret = read(newfd, buf, BUFSIZE-1);}while(ret <1);if(ret <0){exit(1);}if(!ret){break;}printf("receive data:%s\n", buf);if(!strncasecmp(buf, QUIT_STR, strlen(QUIT_STR))){printf("Client is exiting!\n");break;}}
close(newfd);
close(fd);
return 0;​

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot+vue+uniapp的校园二手交易小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

【PyQt】使用PyQt5和Matplotlib实现的CSV数据可视化工具

使用PyQt5和Matplotlib实现的CSV数据可视化工具 界面展示 代码 import sys from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,QHBoxLayout, QPushButton, QComboBox, QFileDialog,QLabel, QMessageBox) import pandas as pd from matplotlib.f…

软件工程导论三级项目报告--《软件工程》课程网站

《软件工程》课程网站 摘要 本文详细介绍了《软件工程》课程网站的设计与实现方案&#xff0c;包括可行性分析、需求分析、总体设计、详细设计、测试用例。首先&#xff0c;通过可行性分析从各方面确认了该工程的可实现性&#xff0c;接着需求分析明确了系统的目标用户群和功能…

数据结构-堆和PriorityQueue

1.堆&#xff08;Heap&#xff09; 1.1堆的概念 堆是一种非常重要的数据结构&#xff0c;通常被实现为一种特殊的完全二叉树 如果有一个关键码的集合K{k0,k1,k2,...,kn-1}&#xff0c;把它所有的元素按照完全二叉树的顺序存储在一个一维数组中&#xff0c;如果满足ki<k2i…

Spring @Lazy:延迟初始化,为应用减负

在Spring框架中&#xff0c;Lazy注解的作用非常直观&#xff0c;它就是用来告诉Spring容器&#xff1a;“嘿&#xff0c;这个Bean嘛&#xff0c;先别急着创建和初始化&#xff0c;等到真正需要用到的时候再弄吧&#xff01;” 默认情况下&#xff0c;Spring容器在启动时会立即创…

SynchronousQueue 与 LinkedBlockingQueue区别及应用场景

文章目录 前言认识SynchronousQueue基本对比及比较1. **基本特性**2. **内部实现**3. **性能特点**4. **使用场景**5. **总结对比** SynchronousQueue案例JDK应用案例案例1&#xff1a;SynchronousQueue的简单用例案例2&#xff1a;SynchronousQueue公平锁、非公平锁案例案例3&…

MySQL 缓存机制与架构解析

目录 一、MySQL缓存机制概述 二、MySQL整体架构 三、SQL查询执行全流程 四、MySQL 8.0为何移除查询缓存&#xff1f; 五、MySQL 8.0前的查询缓存配置 六、替代方案&#xff1a;应用层缓存与优化建议 总结 一、MySQL缓存机制概述 MySQL的缓存机制旨在提升数据访问效率&am…

【C++】STL——list的使用

目录 &#x1f495;1.带头双向链表List &#x1f495;2.list用法介绍 &#x1f495;3.list的初始化 &#x1f495;4.size函数与resize函数 &#x1f495;5.empty函数 &#x1f495;6.front函数与back函数 &#x1f495;7.push_front,push_back,pop_front,pop_back函数…

MySQL知识点总结(一)

1.SQL分类 数据定义&#xff08;DDL&#xff09;:创/改/删/名/清&#xff08;cadrt&#xff09; 数据库对象&#xff1a;表/视图/存储/函数/触发器/事件 数据操作&#xff08;DML&#xff09;&#xff1a;增/删/改/查&#xff08;idus&#xff09; 操作数据库对象 数据控制&…

快速幂,错位排序笔记

​ 记一下刚学明白的快速幂和错位怕排序的原理和代码 快速幂 原理&#xff1a; a^b (a^&#xff08;b/2&#xff09;) ^ 2&#xff08;b为偶数&#xff09; a^b a*&#xff08;a^&#xff08; (b-1)/2&#xff09;&#xff09;^2&#xff08;b为奇数&#xff09; 指数为偶数…

【缴纳过路费——并查集】

题目 分析 题目乍看一下像最短路径的求解。但是从复杂度上面分析应该不是这样。题目关键点在于“路程花费是最贵的那一段” 和 “最少花费在区间内”。 合起来就是两点所有路程中最便宜的最贵段&#xff0c;要在区间内&#xff1a;如果按权值从小到大遍历边&#xff0c;能合并连…

ComfyUI安装调用DeepSeek——DeepSeek多模态之图形模型安装问题解决(ComfyUI-Janus-Pro)

ComfyUI 的 Janus-Pro 节点&#xff0c;一个统一的多模态理解和生成框架。 试用&#xff1a; https://huggingface.co/spaces/deepseek-ai/Janus-1.3B https://huggingface.co/spaces/deepseek-ai/Janus-Pro-7B https://huggingface.co/spaces/deepseek-ai/JanusFlow-1.3B 安装…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.22 多项式运算:从求根到拟合的数值方法

2.22 多项式运算&#xff1a;从求根到拟合的数值方法 目录 #mermaid-svg-D0vp87eTMLHIY39y {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-D0vp87eTMLHIY39y .error-icon{fill:#552222;}#mermaid-svg-D0vp87eTMLHI…

【MySQL】MySQL经典面试题深度解析

文章目录 一、MySQL与C的深度结合1.1 为什么C项目需要MySQL&#xff1f;1.2 典型应用场景 二、基础概念面试题精讲2.1 存储引擎对比2.2 索引原理 三、C专项面试题解析3.1 连接池实现3.2 预处理语句3.3 批量操作优化 四、高级应用面试题剖析4.1 事务隔离级别4.2 锁机制详解4.3 查…

(脚本学习)BUU18 [CISCN2019 华北赛区 Day2 Web1]Hack World1

自用 题目 考虑是不是布尔盲注&#xff0c;如何测试&#xff1a;用"1^1^11 1^0^10&#xff0c;就像是真真真等于真&#xff0c;真假真等于假"这个测试 SQL布尔盲注脚本1 import requestsurl "http://8e4a9bf2-c055-4680-91fd-5b969ebc209e.node5.buuoj.cn…

互联网行业常用12个数据分析指标和八大模型

本文目录 前言 一、互联网线上业务数据分析的12个指标 1. 用户数据&#xff08;4个&#xff09; (1) 存量&#xff08;DAU/MAU&#xff09; (2) 新增用户 (3) 健康程度&#xff08;留存率&#xff09; (4) 渠道来源 2. 用户行为数据&#xff08;4个&#xff09; (1) 次数/频率…

Verilog语言学习总结

Verilog语言学习&#xff01; 目录 文章目录 前言 一、Verilog语言是什么&#xff1f; 1.1 Verilog简介 1.2 Verilog 和 C 的区别 1.3 Verilog 学习 二、Verilog基础知识 2.1 Verilog 的逻辑值 2.2 数字进制 2.3 Verilog标识符 2.4 Verilog 的数据类型 2.4.1 寄存器类型 2.4.2 …

知识蒸馏教程 Knowledge Distillation Tutorial

来自于&#xff1a;Knowledge Distillation Tutorial 将大模型蒸馏为小模型&#xff0c;可以节省计算资源&#xff0c;加快推理过程&#xff0c;更高效的运行。 使用CIFAR-10数据集 import torch import torch.nn as nn import torch.optim as optim import torchvision.tran…

使用SpringBoot发送邮件|解决了部署时连接超时的bug|网易163|2025

使用SpringBoot发送邮件 文章目录 使用SpringBoot发送邮件1. 获取网易邮箱服务的授权码2. 初始化项目maven部分web部分 3. 发送邮件填写配置EmailSendService [已解决]部署时连接超时附&#xff1a;Docker脚本Dockerfile创建镜像启动容器 1. 获取网易邮箱服务的授权码 温馨提示…

docker pull Error response from daemon问题

里面填写 里面解决方案就是挂代理。 以虚拟机为例&#xff0c;将宿主机配置端口设置&#xff0c;https/http端口设为7899 配置虚拟机的http代理&#xff1a; vim /etc/systemd/system/docker.service.d/http-proxy.conf里面填写&#xff0c;wq保存 [Service] Environment…