C/C++网络编程笔记Socket

https://www.bilibili.com/video/BV11Z4y157RY/?vd_source=d0030c72c95e04a14c5614c1c0e6159b

上面链接是B站的博主教程,源代码来自上面视频,侵删,这里只是做笔记,以供复习和分享。

上一篇博客我记录了配置环境并且跑通了,以及碰到的一些问题https://blog.csdn.net/weixin_42324904/article/details/129238003?spm=1001.2014.3001.5501

这篇文章是对socket的代码解读笔记。

先把服务端和客户端的代码放出来(来自B站链接)

Server.cpp

/*
 * 程序名:server.cpp,此程序用于演示socket通信的服务端
 * 作者:C语言技术网(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main(int argc,char *argv[])
{
    if (argc!=2)
    {
        printf("Using:./server port\nExample:./server 5005\n\n"); return -1;
    }

    // 第1步:创建服务端的socket。
    int listenfd;
    if ( (listenfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; }

    // 第2步:把服务端用于通信的地址和端口绑定到socket上。
    struct sockaddr_in servaddr;    // 服务端地址信息的数据结构。
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family = AF_INET;  // 协议族,在socket编程中只能是AF_INET。
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);          // 任意ip地址。
    //servaddr.sin_addr.s_addr = inet_addr("192.168.190.134"); // 指定ip地址。
    servaddr.sin_port = htons(atoi(argv[1]));  // 指定通信端口。
    if (bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) != 0 )
    { perror("bind"); close(listenfd); return -1; }

    // 第3步:把socket设置为监听模式。
    if (listen(listenfd,5) != 0 ) { perror("listen"); close(listenfd); return -1; }

    // 第4步:接受客户端的连接。
    int  clientfd;                  // 客户端的socket。
    int  socklen=sizeof(struct sockaddr_in); // struct sockaddr_in的大小
    struct sockaddr_in clientaddr;  // 客户端的地址信息。
    clientfd=accept(listenfd,(struct sockaddr *)&clientaddr,(socklen_t*)&socklen);
    printf("客户端(%s)已连接。\n",inet_ntoa(clientaddr.sin_addr));

    // 第5步:与客户端通信,接收客户端发过来的报文后,回复ok。
    char buffer[1024];
    while (1)
    {
        int iret;
        memset(buffer,0,sizeof(buffer));
        if ( (iret=recv(clientfd,buffer,sizeof(buffer),0))<=0) // 接收客户端的请求报文。
        {
            printf("iret=%d\n",iret); break;
        }
        printf("接收:%s\n",buffer);
        strcpy(buffer,"ok");
        if ( (iret=send(clientfd,buffer,strlen(buffer),0))<=0) // 向客户端发送响应结果。
        { perror("send"); break; }
        printf("发送:%s\n",buffer);
    }
    // 第6步:关闭socket,释放资源。
    close(listenfd); close(clientfd);
}

Client.cpp

/*
 * 程序名:client.cpp,此程序用于演示socket的客户端
 * 作者:C语言技术网(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main(int argc,char *argv[])
{
  if (argc!=3)
  {
    printf("Using:./client ip port\nExample:./client 127.0.0.1 5005\n\n"); return -1;
  }

  // 第1步:创建客户端的socket。
  int sockfd;
  if ( (sockfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; }
 
  // 第2步:向服务器发起连接请求。
  struct hostent* h;
  if ( (h = gethostbyname(argv[1])) == 0 )   // 指定服务端的ip地址。
  { printf("gethostbyname failed.\n"); close(sockfd); return -1; }
  struct sockaddr_in servaddr;
  memset(&servaddr,0,sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(atoi(argv[2])); // 指定服务端的通信端口。
  memcpy(&servaddr.sin_addr,h->h_addr,h->h_length);
  if (connect(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr)) != 0)  // 向服务端发起连接清求。
  { perror("connect"); close(sockfd); return -1; }

  char buffer[1024];
  // 第3步:与服务端通信,发送一个报文后等待回复,然后再发下一个报文。
  for (int ii=0;ii<3;ii++)
  {
    int iret;
    memset(buffer,0,sizeof(buffer));
    sprintf(buffer,"这是第%d个超级女生,编号%03d。",ii+1,ii+1);
    if ( (iret=send(sockfd,buffer,strlen(buffer),0))<=0) // 向服务端发送请求报文。
    { perror("send"); break; }
    printf("发送:%s\n",buffer);

    memset(buffer,0,sizeof(buffer));
    if ( (iret=recv(sockfd,buffer,sizeof(buffer),0))<=0) // 接收服务端的回应报文。
    {
       printf("iret=%d\n",iret); break;
    }
    printf("接收:%s\n",buffer);
  }

  // 第4步:关闭socket,释放资源。
  close(sockfd);
}


https://pubs.opengroup.org/onlinepubs/007908799/xns/syssocket.h.html

C++文档,我会把实现上面代码的相关内容记录下来。


if (argc!=3)
{
printf("Using:./client ip port\nExample:./client 127.0.0.1 5005\n\n"); return -1;
}

小白看到这个可能会觉得有点懵,argc指的就是程序运行时侯发给main函数的命令行参数的个数,默认为1。argc = 3就说明带了两个参数,例如127.0.0.1 5005,就传了两个参数,如果只传一个参数的话就是2. argv[]是一个字符串数组,在我们这里没用到。

服务器端只需要一个端口号就可以,而客户端需要访问服务器的地址+端口,所以需要两个参数。

先看服务器端,服务器端检测是否传入端口号,传入端口号格式正确之后,先要创建一个Socket,两个不同的机子通信都是要根据地址和端口的嘛,用到网络协议什么的,最终实际上都是两个进程的通信。

服务器要有一个socket,客户机也要有一个socket,通过这两个socket实现互相通信的功能。

int listenfd;
if ( (listenfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; }
  

https://pubs.opengroup.org/onlinepubs/007908799/xns/socket.html

查看socket文档,三个参数domain, type, protocal,指定的参数含义在下图所示。

sockaddr_in是一个数据结构,用来存地址信息,代码中有各个成员变量的含义。

在建立了socket之后返回一个文件描述符,bind是要将文件描述符和地址信息绑定。

同样的客户端也需要有一个socket,服务端就要等待客户端的socket信息。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nginx——Nginx的优化设计

摘要 本博文介绍Nginx的优化设计方向和原理&#xff0c;帮助大家在nginx的使用和优化中提供一个参考的方向&#xff0c;让你的nginx发挥最大性能&#xff0c;节约系统资源。 一、Nginx开启Http2.0的优化 HTTP/2是HTTP协议的最新标准&#xff0c;它是HTTP/1.1的继承者。由于它…

大厂与小厂招人的区别,看完多少有点不敢相信

前两天在头条发了一条招人的感慨&#xff0c;关于大厂招人和小公司招人的区别。 大厂&#xff1a;有影响力&#xff0c;有钱&#xff0c;能够吸引了大量的应聘者。因此&#xff0c;也就有了筛选的资格&#xff0c;比如必须985名校毕业&#xff0c;必须35岁以下&#xff0c;不能…

数据结构与算法这么难,为什么我们还要学习?

文章目录前言1. 数据结构与算法是什么&#xff1f;2. 为什么数据结构与算法很难&#xff1f;3. 如何系统学习数据结构与算法&#xff1f;&#x1f351; 复杂度&#x1f351; 线性表&#x1f351; 树形结构&#x1f351; 图&#x1f351; 排序&#x1f351; 字符串&#x1f351;…

【c++】:模拟实现STL模板中的string

文章目录 前言一.string的模拟实现总结前言 上一篇文章我们详细介绍了STL中的string的一些常用的接口&#xff0c;这一篇文章我们将从底层实现string类&#xff0c;当然我们只是实现一些重要的&#xff0c;经常使用的接口&#xff0c;并且不是完全按照STL中的string去走的。 一…

对于从事芯片行业的人来说,有哪些知识是需要储备的?

近两年芯片行业大火&#xff0c;不少同学想要转行&#xff0c;却不知道该如何下手&#xff0c;需要学习哪些基础知识&#xff0c;下面就来看看资深工程师怎么说&#xff1f; 随着工艺的发展&#xff0c;芯片肯定是尺寸越来越小&#xff0c;至于小到什么样的程度是极限&#xf…

【小破站下载工具】Python tkinter 实现网站下载工具,所有数据一键获取

目录前言开发环境本次项目案例步骤先展示下完成品的效果界面导入模块先创建个窗口功能按键主要功能代码编写功能一功能二功能三前言 最近很多同学想问我&#xff0c;怎么把几个代码的功能集合到一起&#xff1f; 很简单&#xff0c;写一个界面就行了&#xff0c;想要哪个代码…

CSS的三大特性

&#x1f31f;所属专栏&#xff1a;前端只因变凤凰之路&#x1f414;作者简介&#xff1a;rchjr——五带信管菜只因一枚&#x1f62e;前言&#xff1a;该系列将持续更新前端的相关学习笔记&#xff0c;欢迎和我一样的小白订阅&#xff0c;一起学习共同进步~&#x1f449;文章简…

用ChatGPT生成Excel公式,太方便了

ChatGPT 自去年 11 月 30 日 OpenAI 重磅推出以来&#xff0c;这款 AI 聊天机器人迅速成为 AI 界的「当红炸子鸡」。一经发布&#xff0c;不少网友更是痴迷到通宵熬夜和它对话聊天&#xff0c;就为了探究 ChatGPT 的应用天花板在哪里&#xff0c;经过试探不少人发现&#xff0c…

vue3+vite项目移动端适配:postcss-pxtorem和amfe-flexible

一&#xff0c;定义 postcss-pxtorem PostCSS 的一个插件&#xff0c;可以从像素单位生成 rem 单位。 amfe-flexible amfe-flexible是配置可伸缩布局方案&#xff0c;主要是将1rem设为viewWidth/10。 二&#xff0c;使用 1. 设置 viewport 在 index.html 中&#xff1a; &l…

学生信息表

目录 一、功能说明 二、核心思想 三、所用知识回顾 四、基本框架 五、js功能实现部分 一、功能说明 &#xff08;1&#xff09;输入对应的信息&#xff0c;点击录入可以为下面的表格添加一条记录&#xff0c;注意当所填信息不完整时不允许进行提交。 &#xff08;2&…

UE实现建筑生长(材质遮罩方式)效果

文章目录 1.实现目标2.实现过程2.1 遮罩2.2 生长动画3.参考资料1.实现目标 在UE中实现建筑的生成动画效果,GIF动图如下: 2.实现过程 通过动态设置材质遮罩OpacityMask的参数,即通过材质方式来实现建筑生长效果 2.1 遮罩 现有的教程中大多通过BoxMask-3D材质节点实现,但是…

扫地机器人(蓝桥杯C/C++)

题目描述 小明公司的办公区有一条长长的走廊&#xff0c;由 NN 个方格区域组成&#xff0c;如下图所示。 走廊内部署了 KK 台扫地机器人&#xff0c;其中第 ii 台在第 A_iAi​ 个方格区域中。已知扫地机器人每分钟可以移动到左右相邻的方格中&#xff0c;并将该区域清扫干净。…

Linux信号

目录 信号入门 1. 生活角度的信号 2. 技术应用角度的信号 3. 注意 4. 信号概念 5. 用kill -l命令可以察看系统定义的信号列表 6. 信号处理常见方式概览 产生信号 1. 通过终端按键产生信号 2. 调用系统函数向进程发信号 3. 由软件条件产生信号 4. 硬件异常产生信号 核…

DHCP原理简析及交互实践

环境&#xff1a; os&#xff1a;centos7 dnsmasq&#xff1a;version 2.76 一. dhcp工作原理 首先补充几个dhcp相关的基本概念&#xff1a; 1、动态主机配置协议DHCP&#xff08;Dynamic Host Configuration Protocol&#xff09;是一种网络管理协议&#xff0c;用于集中对用…

程序员必会技能—— 使用日志

目录 1、为什么要使用日志 2、自定义日志打印 2.1、在程序中得到日志对象 2.2、使用日志对象打印日志 2.3、日志格式 3、日志的级别 3.1、日志级别的分类 3.2、日志级别的设置 4、持久化日志 5、更简单的日志输出——lombok 5.1、如何在已经创建好的SpringBoot项目中添加…

Python+ChatGPT实战之进行游戏运营数据分析

文章目录一、数据二、目标三、解决方案1. DAU2. 用户等级分布3. 付费率4. 收入情况5. 付费用户的ARPU最近ChatGPT蛮火的&#xff0c;今天试着让ta写了一篇数据分析实战案例&#xff0c;大家来评价一下&#xff01;一、数据 您的团队已经为您提供了一些游戏数据&#xff0c;包括…

MySQL数据库的基础语法总结(1)

MySql一.数据库,数据表的基本操作1.数据库的基本操作2. 数据表的基本操作2.1 数据库的数据类型2.1.1 整数类型2.1.2 浮点数类型和定点数类型2.1.3 字符串类型2.1.4 日期与时间类型2.2 数据表的基本操作2.2.1 创建一个数据表2.2.2 查看数据表2.2.3 查看表的基本信息的MySQL指令2…

【拳打蓝桥杯】最基础的数组你真的掌握了吗?

文章目录一&#xff1a;数组理论基础二&#xff1a;数组这种数据结构的优点和缺点是什么&#xff1f;三&#xff1a;数组是如何实现随机访问的呢&#xff1f;四&#xff1a;低效的“插入”和“删除”原因在哪里&#xff1f;五&#xff1a;实战解题1. 移除元素暴力解法双指针法2…

前端开发神器VS Code安装教程

✅作者简介&#xff1a;CSDN一位小博主&#xff0c;正在学习前端 &#x1f4c3;个人主页&#xff1a;白月光777的CSDN博客 &#x1f4ac;个人格言&#xff1a;但行好事&#xff0c;莫问前程 安装VS CodeVS Code简介VS Code安装VS Code汉化结束语&#x1f4a1;&#x1f4a1;&…

嵌入式学习笔记——STM32的USART收发字符串及串口中断

USART收发字符串及串口中断前言字符串的收发发送一个字符串接收字符串需求利用串口实现printf中断中断是什么前言 上一篇中&#xff0c;介绍了串口收发相关的寄存器&#xff0c;通过代码实现了一个字节的收发&#xff0c;本文接着上面的内容&#xff0c;通过功能函数实现字符串…