当前位置: 首页 > news >正文

0814 TCP和DUP通信协议

Part 1.牛客网刷题

Part 2.思维导图

一.socket

        1.作用

创建套接字函数

        2.函数原型

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

函数参数:

int domain:通信域

AF_UNIX, AF_LOCAL        本地通信        man 7 unix

AF_INET                            IPv4                man 7 ip

AF_INET6                          IPv6                man 7 ipv6

int type:传输层协议类型

SOCK_STREAM        TCP协议

OCK_DGRAM            UDP协议

int protocol

0

二.bind

        1.作用

给套接字文件设置地址

        2.函数原型

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

int sockfd:嵌套字函数文件描述符

const struct sockaddr *addr:地址信息结构体

对于IPv4(AF_INET   ):

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 */

};

需要自己创建sockaddr_in类型的结构体,并对结构体进行赋值,最后往函数内传入结构体地址

对于本地通信(AF_UNIX):

struct sockaddr_un

{

        sa_family_t sun_family; /* AF_UNIX */

        char sun_path[108]; /* pathname */

};

socklen_t addrlen:结构体大小

三.listen

        1.作用

将给定的套接字文件设为监听状态

        2.函数原型

int listen(int sockfd, int backlog);

int sockfd:套接字文件文件描述符

int backlog:一次接收多少个客户端,等待队列的长度

四.accept

        1.作用

在接收到客户端请求后创建一个新的套接字文件用来通信

        2.函数原型

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

参数:

int sockfd:用于监听的套接字文件描述符

struct sockaddr *addr:接收客户套接字文件地址信息的指针

socklen_t *addrlen:客户套接字文件地址信息长度

五.connect

        1.作用

发送到服务器端申请连接的请求

        2.函数原型

 int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
参数:

int sockfd:客户端套接字文件描述符

const struct sockaddr *addr:服务器端套接字文件地址信息的指针

socklen_t addrlen:服务器端套接字文件地址信息长度

Part 3.基于IPC通信的服务器端和客户端实现

1.service.c

#include<myhead.h>#define SER_PORT 8888//端口号
#define SER_IP "192.168.109.62"//IPint main(int argc, const char *argv[])
{//创建一个用于连接的套接字int sfd = socket(AF_INET,SOCK_STREAM,0);//创建一个IPv4&TCP的套接字文件if(-1 == sfd)ERR_MSG("socket error");//判断是否创建成功printf("socket success\n");//给套接字绑定IP地址和端口号struct sockaddr_in sin;//地址信息结构体变量//变量赋值sin.sin_family = AF_INET;//通信域地址族sin.sin_port = htons(SER_PORT);//端口号(将端口转为网络字节序)sin.sin_addr.s_addr = inet_addr(SER_IP);//IP地址(将IP地址转为网络字节序)//绑定if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin)) == -1)ERR_MSG("bind error");printf("bind success\n");//启动套接字监听if(listen(sfd,128) == -1)ERR_MSG("listen error");printf("listen success\n");//阻塞客户端,知道有用户端连接//创建一个用于连接的套接字文件struct sockaddr_in cin;socklen_t addrlen = sizeof(cin);//等待客户端连接,阻塞服务端int new_fd = accept(sfd,(struct sockaddr *)&cin,&addrlen);if(-1 == new_fd)ERR_MSG("accept error");printf("[%s:%d]发来连接 fd:%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),new_fd);//使用新套接字跟客户端进行通信while(1){//从套接字中读取消息char rbuf[128] = "";          //存放接受消息的容器int res = read(new_fd, rbuf, sizeof(rbuf)-1);if(res == 0){printf("客户端已下线\n");close(new_fd);break;}if(res == -1){perror("read error");close(new_fd);close(sfd);return -1;}printf("[%s:%d] : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), rbuf);strcat(rbuf, " 已读");//向套接字中写入消息write(new_fd, rbuf, strlen(rbuf));printf("发送成功\n");}//6、关闭监听套接字close(sfd);return 0;
}

2.client.c

#include<myhead.h>#define  SER_PORT 8888               //服务器端口号
#define SER_IP "192.168.109.62"     //服务器ip地址
#define CLIENT_PORT 9999             //客户端端口号
#define CLIENT_IP "192.168.109.62" //客户端ip地址int main(int argc, const char *argv[])
{//创建一个用于通信的套接字文件int cfd = socket(AF_INET,SOCK_STREAM,0);if(-1 == cfd)ERR_MSG("socket srror");printf("socket success\n");//连接服务器//创建封装服务器端信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;            //通信域sin.sin_port = htons(SER_PORT);     //服务器端口号sin.sin_addr.s_addr = inet_addr(SER_IP);    //服务器ip地址//连接if(connect(cfd,(struct sockaddr *)&sin,sizeof(sin)) == -1)ERR_MSG("connect error");printf("connect success\n");//数据收发while(1){char wbuf[128] = "";            //用于发送数据的容器fgets(wbuf, sizeof(wbuf), stdin);    //从终端获取消息wbuf[strlen(wbuf)-1] = '\0';         //将换行改成'\0'if(strcmp(wbuf, "quit") == 0){break;}//将数据发送给服务器write(cfd, wbuf, strlen(wbuf));printf("发送成功\n");//接收服务器发送的消息read(cfd, wbuf, sizeof(wbuf));printf("收到的消息为:%s\n", wbuf);}//5关闭套接字close(cfd);return 0;
}

http://www.dtcms.com/a/331667.html

相关文章:

  • 【DFS系列 | 暴力搜索与回溯剪枝】DFS问题实战:如何通过剪枝优化暴力搜索效率
  • Java Map集合精讲:键值对高效操作指南
  • (LeetCode 每日一题) 1780. 判断一个数字是否可以表示成三的幂的和 (数学、三进制数)
  • 【lucene】DocumentsWriterFlushControl
  • Linux与Windows文件共享:Samba配置指南
  • Linux软件编程:进程
  • GoLand 项目从 0 到 1:第八天 ——GORM 命名策略陷阱与 Go 项目启动慢问题攻坚
  • Go 并发控制利器 ants 使用文档
  • Uniapp 中的 uni.vibrate 震动 API 使用指南
  • 4. 索引数据的增删改查
  • ATAM:基于场景的软件架构权衡分析法
  • C语言指针使用
  • 机器翻译:Hugging Face库详解
  • Qwen-Image深度解析:突破文本渲染与图像编辑的视觉革命
  • 网站突然崩了,此站点遇到了致命错误!
  • 从零开始学习:深度学习(基础入门版)(第2天)
  • RCL 2025 | LLM采样机制的新视角:来自处方性偏移的解释
  • 区块链技术原理(10)-以太坊帐户
  • ​​vdbench 存储性能测试工具​​的详细使用教程,结合安装部署、参数配置、测试执行及结果分析
  • 电池模组奇异值分解降阶模型
  • Pandas数据处理与分析实战:Pandas数据转换与处理基础课程
  • 既然是长连接 ,资源已经占用,已经存在。那抢购就直接用长连接不更好?
  • 前端八股文-HTML5篇
  • AI绘画:从算法原理解读其风格、质量与效率变革
  • RLHF综述-GRPO之前
  • 《SeeClick: Harnessing GUI Grounding for Advanced Visual GUI Agents》论文精读笔记
  • 机器学习算法篇(八)-------svm支持向量机
  • 机器人“ChatGPT 时刻”倒计时
  • 码上爬第九题【协程+webpack】
  • 苹果正计划大举进军人工智能硬件领域