篇四 tcp,udp客户端服务器编程模型

一 前言

本篇内容主要介绍tcp,udp客户端服务器编程的基础API和示例代码。

二 API

API用途使用方
socket创建套接字,这是网络通信的桥梁Tcp,udp客户端,服务器
bind绑定本地IP地址和端口Tcp,udp客户端,服务器
listen监听端口,等待客户端连接tcp服务器
accept阻塞直到客户端连接,返回新sockettcp服务器
connect主动连接服务器tcp客户端
Recv,send收发Tcp 客户端服务器
Recvfrom,sendto收发Udp 客户端服务器

三 ubuntu下代码示例

  1. TCP server
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>#define SA struct sockaddrint main(int argc,const  char *argv[])
{int sockfd = socket(AF_INET,SOCK_STREAM,0);  //AF_INET  IPV4;SOCK_STREAM  TCP   SOCK_DGRAM  UDPif (sockfd < 0){perror("fail to socket");exit(1);}struct sockaddr_in my_addr,peer_addr;bzero(&my_addr,sizeof(my_addr));my_addr.sin_family = AF_INET;my_addr.sin_port = htons(8080);//转换字节序my_addr.sin_addr.s_addr = inet_addr("0.0.0.0");//inet_addr 把 IP 地址字符串转为整数;0.0.0.0表示绑定所有可用本地 IP,包括本地回环ip:127.0.0.1int ret_bind = bind(sockfd,(SA*)&my_addr,sizeof(my_addr));//绑定socket和本机ip,portif (ret_bind < 0){perror("fail to bind");exit(1);}char buf[128];socklen_t len = sizeof(peer_addr);listen(sockfd,5); //将绑定端口后的socket改为监听状态,准备接收客户端连接请求,5表示等待建立连接的队列的长度,并不是服务器所连客户端数目int ret_recv;while(1){int confd = accept(sockfd,(SA*)&peer_addr,&len); //调用后,如果 accept() 成功,peer_addr 中会被内核写入发起连接的客户端的 IP 地址和端口号if (confd < 0){perror("fail to accept");exit(1);}printf("ip:%s,port:%d is connect\n",inet_ntoa(peer_addr.sin_addr),ntohs(peer_addr.sin_port));while(1){bzero(buf,sizeof(buf));ret_recv = recv(confd,buf,sizeof(buf),0);if (ret_recv < 0){perror("fail to recv");//perror可以打印系统调用错误信息,括号内为打印字头close(confd);break;}else if (ret_recv == 0){printf("peer is shutdown\n");close(confd);break;}else{printf("%s\n",buf);send(confd,buf,ret_recv,0);}}}return 0;
}注:
1.在上面这些接口里面,只有accept和recv是阻塞的,其他立即返回
accept:  阻塞等待客户端连接,直到有连接请求到达才返回
recv:    阻塞等待接收数据,直到有数据可读或连接关闭
2.可用telnet 127.0.0.1 8080来测试
(1)telnet是一个远程登录与测试通信的命令行工具,基于tcp协议,不能用来测试udp
(2)相当于创建一个tcp client 去连接服务器 127.0.0.18080端口,实现命令行交互
  1. TCP client
#include <stdio.h>
#include <sys/types.h>	       /* See NOTES */
#include <sys/socket.h>
#include <strings.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>#define SA struct sockaddr
int main(int argc,const char* argv[])
{if (argc != 3){printf("please input ip,port\n");exit(1);}int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建一个套接字if (sockfd < 0){perror("fail to socket\n");exit(1);}struct sockaddr_in my_addr,peer_addr;bzero(&my_addr,sizeof(my_addr));my_addr.sin_family = AF_INET;my_addr.sin_port = htons(6000);my_addr.sin_addr.s_addr = inet_addr("0.0.0.0");int ret_bind = bind(sockfd,(SA*)&my_addr,sizeof(my_addr));//将套接字和本机ip,port绑定if(ret_bind < 0){perror("fail to bind\n");close(sockfd);exit(1);}char buf[128];socklen_t len = sizeof(peer_addr);bzero(&peer_addr,sizeof(peer_addr));peer_addr.sin_family = AF_INET;peer_addr.sin_port = htons(atoi(argv[2]));peer_addr.sin_addr.s_addr = inet_addr(argv[1]);int ret_connect = connect(sockfd,(SA*)&peer_addr,len);//connect 连接服务器if (ret_connect < 0){perror("fail to connect\n");close(sockfd);exit(1);}while(1){bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin);send(sockfd,buf,strlen(buf),0);bzero(buf,sizeof(buf));recv(sockfd,buf,sizeof(buf),0);printf("%s\n",buf);}return 0;}
  1. UDP server
#include <stdio.h>
#include <sys/types.h>	       /* See NOTES */
#include <sys/socket.h>
#include <strings.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>#define SA struct sockaddr
int main(int argc,const char*argv)
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);if (sockfd < 0){perror("fail to socket\n");exit(1);}struct sockaddr_in my_addr,peer_addr;socklen_t len=sizeof(peer_addr);bzero(&my_addr,sizeof(my_addr));my_addr.sin_family = AF_INET;my_addr.sin_port = htons(8080);my_addr.sin_addr.s_addr = inet_addr("0.0.0.0");int ret_bind = bind(sockfd,(SA*)&my_addr,sizeof(my_addr));if (ret_bind < 0){perror("fail to bind\n");close(sockfd);exit(1);}char buf[128];while(1){bzero(buf,sizeof(buf));bzero(&peer_addr,len);recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)(&peer_addr),&len); //接收到数据时才知道对端信息printf("ip:%s port:%d buf:%s \n",inet_ntoa(peer_addr.sin_addr),ntohs(peer_addr.sin_port),buf);sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&peer_addr,len);}return 0;
}//recvfrom,sendto和tcp recv,send是不一样的接口
//nc 是一个强大的网络调试工具 nc -u 127.0.0.1 8080 可用来创建udp客户端来测试

4.udp client

#include <stdio.h>
#include <sys/types.h>	       /* See NOTES */
#include <sys/socket.h>
#include <strings.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>#define SA struct sockaddr
int main(int argc,const char*argv[])
{if (argc != 3){printf("please input ip and port\n");return -1;}int sockfd = socket(AF_INET,SOCK_DGRAM,0);if (sockfd < 0){perror("fail to socket\n");exit(1);}struct sockaddr_in my_addr,peer_addr;bzero(&my_addr,sizeof(my_addr));my_addr.sin_family = AF_INET;my_addr.sin_port = htons(6000);my_addr.sin_addr.s_addr = inet_addr("0.0.0.0");int ret_bind = bind(sockfd,(SA*)&my_addr,sizeof(my_addr));if (ret_bind < 0){perror("fail to bind\n");close(sockfd);exit(1);}char buf[128];bzero(&peer_addr,sizeof(peer_addr));peer_addr.sin_family = AF_INET;peer_addr.sin_port = htons(atoi(argv[2]));peer_addr.sin_addr.s_addr = inet_addr(argv[1]);while(1){bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin);sendto(sockfd,buf,strlen(buf),0,(SA*)&peer_addr,sizeof(peer_addr));bzero(buf,sizeof(buf));recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);printf("%s\n",buf);}return 0;}

四 总结

1.tcp服务器和客户端编程,最关键的点其实是各调用了哪些API,及API调用顺序,其他都是细枝末节
2.udp相对简单些,API调用较少,但是要注意和tcp调用上的差别,参数,接口不全一样

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

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

相关文章

ESP32学习笔记_Components(1)——使用LED Strip组件点亮LED灯带

LED strip ESP32-S3 的 RMT&#xff08;Remote Control Transceiver&#xff0c;远程控制收发器&#xff09;外设最初设计用于红外收发&#xff0c;但由于其数据格式的灵活性&#xff0c;RMT 可以扩展为通用的信号收发器&#xff0c;能够发送或接收多种类型的信号&#xff1b;…

无人机抛投模块分析

一、设计核心要点1. 结构轻量化与强度平衡 材料选择&#xff1a;主体采用航空铝、碳纤维复合材料&#xff0c;降低自重并保证承重强度。 机械传动优化&#xff1a;齿轮-齿条传动替代传统丝杆结构&#xff0c;简化机构并提升可靠性。 模块化设计&#xff1a;支持多仓位独立控…

【硬件-笔试面试题】硬件/电子工程师,笔试面试题-33,(知识点:二极管结温,热阻,二极管功耗计算)

目录 1、题目 2、解答 步骤一&#xff1a;明确热阻的相关公式 步骤二&#xff1a;计算二极管的功耗 步骤三&#xff1a;计算二极管的结温 3、相关知识点 一、热阻的定义 二、二极管功耗的计算 三、结温的计算 题目汇总版--链接&#xff1a; 【硬件-笔试面试题】硬件…

【LeetCode 热题 100】79. 单词搜索——回溯

Problem: 79. 单词搜索 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格…

ARM SMMUv3控制器注册过程分析(八)

1.概述 ARM SMMUv3控制器初始化及设备树分析&#xff08;七&#xff09;中描述了IOMMU控制器初始化过程。SMMU驱动最后调用iommu_device_register将其注册到内核中&#xff0c;下面分析一下SMMU控制器注册过程中都做了那些工作。 如下图所示&#xff0c;SMMU控制器注册过程中…

Idefics3:构建和更好地理解视觉-语言模型:洞察与未来方向

温馨提示&#xff1a; 本篇文章已同步至"AI专题精讲" Idefics3&#xff1a;构建和更好地理解视觉-语言模型&#xff1a;洞察与未来方向 摘要 视觉-语言模型&#xff08;VLMs&#xff09;领域&#xff0c;接收图像和文本作为输入并输出文本的模型&#xff0c;正在快…

利用DeepSeek解决kdb+x进行tpch测试的几个问题及使用感受

上文其实没有成功运行tpch的22个标准查询中的任何一个&#xff0c;因为DeepSeek原始给出的导入语句有错&#xff0c;有一些表没有导入。 1.解决类型及长度问题导致的插入tbl文件到内存表失败。 kdbx的Reference card()提到的基本数据类型如下&#xff1a; Basic datatypes n …

SGLang 核心技术详解

SGLang 作为一个高性能的 LLM 服务框架&#xff0c;通过一系列先进的优化技术实现了卓越的推理性能。下面详细解释其核心功能组件&#xff1a; 1. RadixAttention 用于前缀缓存 核心概念 RadixAttention 是 SGLang 独创的前缀缓存机制&#xff0c;基于 Radix Tree&#xff08;基…

精密全波整流电路(四)

精密全波整流电路&#xff08;四&#xff09; 背景说明 [[精密半波整流电路|半波整流]]虽然能实现交直流信号的转换&#xff0c;但是半波整流只能保留信号半个周期的能量&#xff0c;导致信号能量的利用率不高。 因此&#xff0c;在一些场合需要使用到全波整流电路。 同样的&…

深入解读Prometheus 2.33 Series Chunks压缩特性:原理与实践

深入解读Prometheus 2.33 Series Chunks压缩特性&#xff1a;原理与实践 随着监控指标规模不断增长&#xff0c;Prometheus的本地TSDB存储压力日益增大。为提升存储效率&#xff0c;Prometheus 2.33引入了Series Chunks压缩特性&#xff0c;对时间序列数据在写入和存储时进行深…

SpringBoot整合Liquibase提升数据库变更的可控性、安全性、自动化程度(最详细)

为什么要使用liquibase?- 团队协作与版本管理- 当多人&#xff08;或多个小组&#xff09;并行开发、对同一数据库结构进行变更时&#xff0c;如果仅靠手写 SQL 脚本&#xff0c;很 容易产生冲突或漏掉某些变更。- Liquibase 将所有 DDL/DML 操作以“changeset”形式纳入源码管…

数据写入因为汉字引发的异常

spark 数据写hive表,发生 查询分区异常问题 异常: 25107124 19 26.49 ERROR Hive: MelaException(message.Exception thrown when execuling quey. S ELECT DISTINCT ‘org apache.hadop.hive melastore .modelMpartion As"NUCLEUS TYPE,AONCREATE TIME,AO.LAST ACCE…

Springboot项目实现将文件上传到阿里云

Springboot项目实现将文件上传到阿里云 一、概述二、具体步骤 2.1引入阿里云工具 首先先建utils包&#xff0c;然后引入AliOSSUtils类&#xff0c;如下&#xff1a; package com.hechixueyuan.forestfiredetectionsystem.utils;import com.aliyun.oss.OSS; import com.aliyun.o…

如何理解 TCP 是字节流协议?详解

文章目录一、面向字节流二、粘包问题应用层如何解决粘包问题&#xff1f;一、面向字节流 使用 TCP socket 进行网络编程&#xff0c;Linux 内核会给每个 socket 都分配一个发送缓冲区和一个接收缓冲区 由于缓冲区的存在, TCP 读写不需要一一匹配&#xff0c;例如&#xff1a;…

面试问题总结——关于OpenCV(二)

最近小组在面试视觉算法工程师,顺便整理了一波关于OpenCV的面试题目。 有些知识点也不深入,对于写的不对的地方,欢迎指正。 目录 20.像素梯度如何计算? 21.关于开运算和闭运算的理解 22.开运算和闭运算有什么优缺点? 23.图像插值有哪些? 24.图像金字塔的原理 25.边缘检测…

目标导向的强化学习:问题定义与 HER 算法详解—强化学习(19)

目录 1、目标导向的强化学习&#xff1a;问题定义 1.1、 核心要素与符号定义 1.2、 核心问题&#xff1a;稀疏奖励困境 1.3、 学习目标 2、HER&#xff08;Hindsight Experience Replay&#xff09;算法 2.1、 HER 的核心逻辑 2.2、 算法步骤&#xff08;结合 DDPG 举例…

2025 XYD Summer Camp 7.21 智灵班分班考 · Day1

智灵班分班考 Day1 时间线 8:00 在滨兰实验的远古机房中的一个键盘手感爆炸的电脑上开考。开 T1&#xff0c;推了推发现可以 segment tree 优化 dp&#xff0c;由于按空格需要很大的力气导致马蜂被迫改变。后来忍不住了顶着疼痛按空格。8:30 过了样例&#xff0c;但是没有大样…

基于多种主题分析、关键词提取算法的设计与实现【TF-IDF算法、LDA、NMF分解、BERT主题模型】

文章目录有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主一、项目背景二、研究目标与意义三、数据获取与处理四、文本分析与主题建模方法1. 传统方法探索2. 主题模型比较与优化3. 深度语义建模与聚类五、研究成果与应用价值六、总结与展望总结每文一…

MDC(Mapped Diagnostic Context) 的核心介绍与使用教程

关于日志框架中 MDC&#xff08;Mapped Diagnostic Context&#xff09; 的核心介绍与使用教程&#xff0c;结合其在分布式系统中的实际应用场景&#xff0c;分模块说明&#xff1a; 一、MDC 简介 MDC&#xff08;映射诊断上下文&#xff09; 是 SLF4J/Logback 提供的一种线程…

Linux随记(二十一)

一、highgo切换leader&#xff0c;follow - 随记 【待写】二、highgo的etcd未授权访问 - 随记 【待写】三、highgo的etcd未授权访问 - 随记 【待写】3.2、etcd的metric未授权访问 - 随记 【待写】四、安装Elasticsearch 7.17.29 和 Elasticsearch 未授权访问【原理扫描】…