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

0814 TCP通信协议

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/332114.html

相关文章:

  • 一款开源的远程桌面软件,旨在为用户提供流畅的游戏体验,支持 2K 分辨率、60 FPS,延迟仅为 40ms。
  • 数据库访问模式详解
  • [TryHackMe](知识学习)---基于堆栈得到缓冲区溢出
  • opencv基础学习与实战(2)
  • Linux中的日志管理
  • 学习嵌入式第二十八天
  • 中山清华:基于大模型的具身智能系统综述
  • app-4 日志上传
  • 从0到1:C++ 语法之引用
  • qt项目中解决关闭弹窗后执行主界面的信号槽时闪退问题
  • 基于wireshark的USB 全速硬件抓包工具USB Sniffer Lite的使用
  • 多线程安全和性能测试
  • 珠海社保缴费记录如何打印
  • MyBatis Interceptor 深度解析与应用实践
  • CTFShow PWN入门---Kernel PWN 356-360 [持续更新]
  • 【嵌入式汇编基础】-ARM架构基础(五)
  • c/c++实现 TCP Socket网络通信
  • Docker存储卷备份策略于VPS服务器环境的实施标准与恢复测试
  • Linux 进程与内存布局详解
  • RecyclerView 拖拽与滑动操作
  • HQA-Attack: Toward High Quality Black-Box Hard-Label Adversarial Attack on Text
  • 多列集合---Map
  • 【无标题】设计文档
  • Cache的基本原理和缓存一致性
  • 基于大语言模型的爬虫数据清洗与结构化
  • 可信搜索中的多重签名
  • 系统日常巡检脚本
  • 将mysql数据库表结构导出成DBML格式
  • Qt---Qt函数库
  • ActionChains 鼠标操作笔记