TCP通信(复习)

news/2024/11/30 20:38:23/

目录

TCP通信实现过程

1、socket函数与通信域

socket函数

 参 数

bind函数 与 通信结构体

bind函数

参数

通信地址族与同届结构体

 通用地址族结构体

IPV4地址族结构体

listen函数与accept函数

listen函数

accept函数

参 数

作 用


要实现进程间的通信必备:IP地址、端口号、协议(TCP or UDP)

TCP通信实现过程

1、建立连接;(socket, bind, listen, accept)

2、数据传输;(read / write,recv / send )

3、连接释放;(close, shutdown)

1、socket函数与通信域

socket函数

#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);

 参 数

-domain :指定通信域(通信地址族);

通信地址族种类:AF_INET : 使用ipv4互联网协议    AF_INET6 : 使用ipv6互联网协议,    等;

这里使用Ipv4;

-type :指定套接字类型;

TCP唯一对应流式套接字,所以选择SOCK_STREAM;

-protocol :指定协议;

流式套接字唯一对应 TCP ,所以不需要指定协议设置为 0 即可;

bind函数 与 通信结构体

bind函数

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

参数

-sockfd :socket函数生成的套接字;

-addr :通信结构体;

-addrlen :通信结构体长度;

通信地址族与同届结构体

通信地址族用于获取IP地址和端口号

 通用地址族结构体

struct sockaddr {sa_family_t sa_family;char        sa_data[14];}

IPV4地址族结构体

struct sockaddr_in {sa_family sin_family;    /*地址族:AF_INET*/in_port_t sin_port;      /*网络字节序的端口号*/struct in_addr sin_addr; /*IP地址结构体*/ 
};/*IP地址结构体*/
struct in_addr {uint32_t s_addr;   /*网络字节序的IP地址*/
};

listen函数与accept函数

listen函数

/*监听套接字*/
int listen(int sockfd, int backlog);

accept函数

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

参 数

-sockfd : 函数socket生成的套接字;

-addr : 客户端的地址族信息;

(struct socketaddr  --->是对应客户端的结构体)

-addrlen : 地址族结构体的长度;

作 用

accept() 函数用于套接字编程,其作用是接受来自客户端的连接请求。具体而言,它用于通信的服务器端接受客户端通过套接字终点发出的连接请求。

当客户端向服务器发起连接时,它会向服务器发送一个 SYN 包。服务器随后会响应一个 SYN-ACK 包。当客户端从服务器接收到 SYN-ACK 包时,它会向服务器发送一个 ACK 包以完成三次握手并建立连接。一旦建立了连接,服务器就会调用 `accept()` 函数来接受客户端的连接请求

`accept()` 函数会阻塞执行,直到收到新的客户端连接。一旦收到连接,`accept()` 函数将返回一个新的套接字描述符,该描述符将用于与客户端进行通信。这个新的套接字描述符表示一个特定客户端已连接到服务器的单独套接字终点。服务器随后可以使用新的套接字描述符来与客户端通信,以实现建立的连接。

inet_aton() 函数

是一个 C 库函数,用于将一个字符串形式的 IPv4 地址转换为一个网络字节序的二进制地址,然后存储到指定的网络地址结构体中。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <strings.h>
#include <signal.h>
#include <sys/wait.h>#define BACKLOG 5void SigHandle(int sig)
{if(sig == SIGCHLD){printf("clinet exited\n");wait(NULL);}}void ClinetHandle(int newfd);int main(int argc, char *argv[])
{int fd ,newfd;struct sockaddr_in addr, clinet_addr;socklen_t addrlen = sizeof(clinet_addr);struct sigaction act;act.sa_handler = SigHandle;act.sa_flags = SA_RESTART;sigemptyset(&act.sa_mask);sigaction(SIGCHLD, &act, NULL);pid_t pid;/*参数检查*/if(argc < 3){fprintf(stderr, "%s<addr><port>\n", argv[0]);exit(0);}/*创建套接字*/fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0) {perror("socket");exit(0);}/*地址快速重用*/int flag = 1, len = sizeof(int);if( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len) == -1){perror("setsockopt");exit(1);}/*设置通信地址族结构体*/addr.sin_family = AF_INET;                   //网络协议;addr.sin_port = htons( atoi(argv[2]) );         //端口号;if (inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*绑定通信地址组*/if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1){perror("bind");exit(0);}/*设置套接字为监听模式*/if(listen(fd, BACKLOG) == -1){perror("listen");exit(0);}/*接收客户端连接请求*/while(1){newfd = accept(fd, (struct sockaddr *)&clinet_addr, &addrlen);if(newfd < 0){perror("accept");exit(0);}printf("addr:%s port:%d\n", inet_ntoa(clinet_addr.sin_addr), ntohs(clinet_addr.sin_port));/*多进程并发*/if((pid = fork()) < 0){perror("fork");exit(0);}else if (pid == 0){close(fd);ClinetHandle(newfd);exit(0);}elseclose(newfd);}/*关闭套接字文件描述符*/close(fd);return 0;
}void ClinetHandle(int newfd)
{int ret;char buf[BUFSIZ] = {};/*循环接收客户端信息*/while(1){memset(buf, 0, BUFSIZ);ret = read(newfd, buf, BUFSIZ);if(ret < 0){perror("read");exit(0);}else if(ret == 0){break;}else{printf("buf=%s\n", buf);}}close(newfd);}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>#define BACKLOG 5int main(int argc, char *argv[])
{int fd;char buf[BUFSIZ] = {};      struct sockaddr_in addr;/*参数检查*/if(argc < 3){fprintf(stderr, "%s<addr><port>\n", argv[0]);exit(0);}/*创建套接字*/fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0) {perror("socket");exit(0);}/*设置通信地址族结构体*/addr.sin_family = AF_INET;                   //网络协议;addr.sin_port = htons( atoi(argv[2]) );         //端口号;if (inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*向服务器发起连接请求*/if( connect(fd,(struct sockaddr *)&addr, sizeof(addr)) == -1 ){perror("connect");exit(0);}/*循环接收客户端信息*/while(1){printf("input:");fgets(buf, BUFSIZ, stdin);write(fd, buf, strlen(buf));}/*关闭套接字文件描述符*/close(fd);return 0;
}


http://www.ppmy.cn/news/109042.html

相关文章

模拟人生打开显示找不到msvcp120.dll如何修复?msvcp120.dll是什么呢?

如果您在打开模拟人生游戏时遇到了msvcp120.dll文件丢失的错误信息&#xff0c;这可能是由于缺少Microsoft Visual C Redistributable for Visual Studio 2013软件包导致的。遇到这个情况不需要着急&#xff0c;只需要修复一下就可以。msvcp120.dll如何修复&#xff1f;下面就把…

linux常见的二十多个指令

目录 一、指令的概念 二、28个常见的指令 ⭐2.1 ls指令 ⭐2.2 pwd指令 ⭐2.3 cd指令 ⭐2.4tree指令 ⭐2.5 mkdir指令 ⭐2.6 touch指令 ⭐2.7 rmdir指令 ⭐2.8 rm指令 ⭐2.9 clear指令 ⭐2.10 man指令 ⭐2.11 cp指令 ⭐2.12 mv指令 ⭐2.13 cat指令&#xff08;适…

二、机器人的结构设计

1 、螺丝连接的坚固性 坚固性是机器人能顺利完成指定任务的一个重要条件&#xff0c;无论我们程序设计的如何完美&#xff0c; 如果不能保证机器人具有坚固性和稳定性&#xff0c;就无法保证任务的顺利完成&#xff0c;机器人在运行时如 果发生散架和分裂都会影响其功能的实现…

如何在 Rocky Linux 上检查磁盘空间?

在 Rocky Linux 上检查磁盘空间是系统管理和维护的重要任务之一。磁盘空间的监控和管理可以帮助我们及时发现和解决存储空间不足的问题&#xff0c;以确保系统的正常运行。本文将详细介绍在 Rocky Linux 上检查磁盘空间的方法。 方法 1&#xff1a;使用 df 命令 df 命令是 Li…

ElasticSearch解析logback日志并处理异常栈轨迹

文章目录 背景分析Ingest Pipeline解析日志 - 示例查看Ingest Pipeline创建Pipeline添加Grok处理器添加时间戳、IP地址和用户代理处理器测试Pipeline多行消息管理filestream inputlog input解决自定义pipeline解析logback日志Grok处理器Date处理器失败处理器为log input添加多行…

谷歌训了28个15亿参数模型,说明数据对大模型训练的影响

夕小瑶科技说 原创 作者 | Python 随着ChatGPT的爆火&#xff0c;大规模语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;如日中天。然而&#xff0c;由于相关数据细节并不公开&#xff0c;相关研究大多都是盲人摸象式探索&#xff0c;缺乏系统的经验指导…

95后阿里P7架构师晒出工资单:狠补了这个,真香...

最近一哥们跟我聊天装逼&#xff0c;说他最近从阿里跳槽了&#xff0c;我问他跳出来拿了多少&#xff1f;哥们表示很得意&#xff0c;说跳槽到新公司一个月后发了工资&#xff0c;月入5万多&#xff0c;表示很满足&#xff01;这样的高薪资着实让人羡慕&#xff0c;我猜这是税后…

【实用篇】SpringCloud02

文章目录 SpringCloud020.学习目标1.Nacos配置管理1.1.统一配置管理1.1.1.在nacos中添加配置文件1.1.2.从微服务拉取配置 1.2.配置热更新1.2.1.方式一1.2.2.方式二 1.3.配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置3&#xff09;运行两…