79-Linux_Socket实现客户端与服务器端间通讯

news2024/11/18 11:42:47

Socket实现客户端与服务器端间通讯

  • 一.网络编程的接口
    • 1.socket
    • 2.bind
    • 3.listen
    • 4.accept
    • 5.connect
    • 6.close
    • 7.ssize_t recv和ssize_t send
    • 8.UDP 数据读写
  • 二.tcp流式服务和粘包问题
  • 三.客户端及服务器端实现的代码.
    • 1.客户端
    • 2.服务器端

一.网络编程的接口

头文件:

#include <sys/types.h>
#include <sys/socket.h>

1.socket

int socket(int domain, int type, int protocol);
//socket()创建套接字,成功返回套接字的文件描述符,失败返回-1
//domain: 设置套接字的协议簇, AF_UNIX AF_INET AF_INET6
//type: 设置套接字的服务类型 SOCK_STREAM SOCK_DGRAM
// protocol: 一般设置为 0,表示使用默认协议

2.bind

int bind(int sockfd, const struct sockaddr *addr, socklen_t
addrlen);
//bind()将 sockfd 与一个 socket 地址绑定,成功返回 0,失败返回-1
//sockfd 是网络套接字描述符,(命名套接字,就是上面的函数的返回值作为了我们的参数sockfd)
//addr 是地址结构
//addrlen 是 socket 地址的长度

3.listen

int listen(int sockfd, int backlog);
//listen()创建一个监听队列以存储待处理的客户连接,成功返回 0,失败返回-1
//sockfd 是被监听的 socket 套接字
//backlog 表示处于完全连接状态的 socket 的上限

4.accept

int accept(int sockfd, struct sockaddr *addr, socklen_t
*addrlen);
//accept()从 listen 监听队列中接收一个连接,成功返回一个新的连接 socket,
//该 socket 唯一地标识了被接收的这个连接,失败返回-1
//sockfd 是执行过 listen 系统调用的监听 socket
//addr 参数用来获取被接受连接的远端 socket 地址
//addrlen 指定该 socket 地址的长度

5.connect

int connect(int sockfd, const struct sockaddr *serv_addr,
socklen_t addrlen);
//connect()客户端需要通过此系统调用来主动与服务器建立连接,
//成功返回 0,失败返回-1
//sockfd 参数是由 socket()返回的一个 socket。
//serv_addr 是服务器监听的 socket 地址
//addrlen 则指定这个地址的长度

6.close

int close(int sockfd);
//close()关闭一个连接,实际上就是关闭该连接对应的 socket

7.ssize_t recv和ssize_t send

ssize_t recv(int sockfd, void *buff, size_t len, int flags);
(int sockfd, const void *buff, size_t len, int
flags);
//TCP 数据读写:
//recv()读取 sockfd 上的数据, buff 和 len 参数分别指定读缓冲区的位置和大小
//send()往 socket 上写入数据, buff 和 len 参数分别指定写缓冲区的位置和数据长度
//flags 参数为数据收发提供了额外的控制

8.UDP 数据读写

//UDP 数据读写:
ssize_t recvfrom(int sockfd, void *buff, size_t len, int flags,
struct sockaddr* src_addr, socklen_t *addrlen);
ssize_t sendto(int sockfd, void *buff, size_t len, int flags,
struct sockaddr* dest_addr, socklen_t addrlen);

//recvfrom()读取 sockfd 上的数据, buff 和 len 参数分别指定读缓冲区的位置和大小
//src_addr 记录发送端的 socket 地址
//addrlen 指定该地址的长度
//sendto()往 socket 上写入数据, buff 和 len 参数分别指定写缓冲区的位置和数据长度
//dest_addr 指定接收数据端的 socket 地址
//addrlen 指定该地址的长度

二.tcp流式服务和粘包问题

tcp服务的特点
在这里插入图片描述
套接字是一个全双工的
在这里插入图片描述
沾包(粘包)有影响就解决,没有影响就不用解决(比如文件传输就没有影响);
重点理解以下图片:
在这里插入图片描述

三.客户端及服务器端实现的代码.

1.客户端

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>

int socket_init();

int main()
{
    int sockfd=socket_init();
    if(sockfd==-1)
    {
        exit(0);
    }

    while(1)
    {
        printf("input:");
        char buff[128]={0}; 
        fgets(buff,127,stdin);
        if(strncmp(buff,"end",3)==0)
        {
            break;
        }
        send(sockfd,buff,strlen(buff)-1,0);

        memset(buff,0,128);
        recv(sockfd,buff,127,0);
        printf("read:%s\n",buff);
    }
    close(sockfd);
    exit(0);
        
}

int socket_init()
{
    int sockfd=socket(AF_INET,SOCK_STREAM,0);//tcp流式服务
    if(sockfd==-1)
    {
        printf("socket errror\n");
        return -1;
    }

    struct sockaddr_in saddr;
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family=AF_INET;
    saddr.sin_port=htons(5678);
    saddr.sin_addr.s_addr=inet_addr("127.0.0.1");


    int res=connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(res==-1)
    {
        printf("connect error\n");
        return -1;
    }
     return sockfd;
}

2.服务器端

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int socket_init();

int main()
{
    int sockfd=socket_init();
    if(sockfd==-1)
    {
        exit(0);
    }
    
    while(1)
    {
        struct sockaddr_in caddr;//记录客户端ip port
        int len=sizeof(caddr);
        int c=accept(sockfd,(struct sockaddr*)&caddr,&len);
        if(c<0)
        {
            continue;
        }
        
        printf("accept client ip:%s,port=%d\n",inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port));
        printf("accept c=%d\n",c);

        while(1)
        {
            char buff[128]={0};
            int n=recv(c,buff,127,0);//阻塞
            if(n<=0)//n<0 出错  n==0 客户端已经关闭  唯一判断对方关闭
            {  
                break;
            }
            printf("read:%s\n",buff);
            send(c,"ok",2,0);//write
        }
        close(c);
    }
    close(sockfd);
    exit(0);
}

int socket_init()
{
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        printf("socket error\n");
        return -1;
    }

    struct sockaddr_in saddr;
    memset(&saddr,0,sizeof(saddr));//清空
    saddr.sin_family=AF_INET;
    saddr.sin_port=htons(5678);//1024内知名端口  //4096保留端口
    saddr.sin_addr.s_addr=inet_addr("127.0.0.1");

    int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(res==-1)
    {
        printf("bind error\n");
        return -1;
    }
    
    res=listen(sockfd,5);
    if(res==-1)
    {
        printf("listen error\n");
        return -1;
    }

    return sockfd;
}

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

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

相关文章

win11使用移动硬盘(固态非固态)卡顿问题解决

以前win10使用移动硬盘没用出现过卡顿的问题&#xff0c;后来更新win11后&#xff0c;硬盘在处理文件和文件新建以及编辑的时候&#xff0c;都会莫名其妙卡1-3秒左右。以为是盘坏了&#xff0c;各种检测和修复。发现没有问题 后来还找移动硬盘的商家沟通&#xff0c;也无果打算…

C语言基础应用(四)选择结构

引言&#xff1a; 在日常生活中&#xff0c;我们时时刻刻面临着选择&#xff0c;在C语言中&#xff0c;如果我们需要判断条件从而实现不同的要求&#xff0c;我们就需要使用选择结构。 注&#xff1a;以下代码均未导入头文件&#xff0c;如果读者使用了代码&#xff0c;请记得…

day9 条件变量的基本使用

目录 条件变量 条件变量 应用场景&#xff1a;生产者消费问题&#xff0c;是线程同步的一种手段&#xff1b; 必要性&#xff1a;为了实现等待某个资源&#xff0c;让线程休眠&#xff0c;提高运行效率&#xff1b; 等待资源&#xff1a; //1、一直等待资源 int pthread_c…

linux 匿名文件 memfd_create

专栏内容&#xff1a;linux下并发编程个人主页&#xff1a;我的主页座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物&#xff0e;目录 前言 概述 原理 接口 代码演示 结尾 前言 本专栏主要分享linux下并发编程相关知识…

慌了!ChatGPT吃我饭,还要掀我碗?

ChatGPT面世&#xff0c;各种被AI取代“失业言论”笼罩在人们头顶&#xff0c;本文聚焦这一问题&#xff0c;推荐关注ChatGPT的小伙伴阅读。 一时间火爆全网的新晋网红——ChatGPT&#xff0c;就问&#xff1a;还有谁不认识&#xff1f; 谷歌计划在旗舰搜索引擎中添加对话式人…

TCP/UDP协议 (详解)

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

网络安全之入侵检测

目录 网络安全之入侵检测 入侵检测经典理论 经典检测模型 入侵检测作用与原理 意义 异常检测模型&#xff08;Anomaly Detection&#xff09; 误用检测模型&#xff08;Misuse Detection&#xff09; 经典特征案例 ​编辑自定义签名 ​编辑 签名检查过程 检测生命周期…

提升 Prometheus 的高可用性:Thanos 的部署与实践!

背景 在高可用 prometheus&#xff1a;问题集锦文章中有简单提到 Prometheus 的高可用方案&#xff0c;尝试了联邦、Remote Write 之后&#xff0c;我们最终选择了 Thanos 作为监控配套组件&#xff0c;利用其全局视图来管理我们的多地域、300集群的监控数据。本文主要介绍 Th…

NC237662 葫芦的考验之定位子串(SAM + 后缀链接树上倍增)

题意&#xff1a; 给出一个字符串S&#xff0c;|S| ≤ 250000&#xff0c;给出 Q < 250000 次询问&#xff0c;每次需要回答 S[l, r] 在 S 中共出现了多少次。 思路&#xff1a; 如果使用 SAM&#xff0c;我们提前求出每个状态的 cnt[u]&#xff0c;询问就是要求我们快速…

Nuxt3中的中间件-middleware

参考&#xff1a;nuxt3中间件(middleware)详解 - 简书nuxt3中间件(middleware)详解 在项目中有时候需要在网站切换路由的过程中添加一些自定义的逻辑&#xff0c;比如权限什么的。这个时候可以使用nuxt的middleware。 ...https://www.jianshu.com/p/bd22637c6447 中间件的作用…

【算法系列之动态规划】子序列篇

300.最长递增子序列 力扣题目链接 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1…

Ubunutu18.04+Qt5.14+Dlib19.24+Opencv3.4.16实时人眼监测实验

文章目录1 前言2 效果3 Ubuntu18.04下Qt、Opencv、Dlib的配置3.0 Ubuntu18.04的安装以及一些基本配置3.1 Qt3.2 Opencv3.3 Dlib4 核心代码4.1 pro文件4.2 Widget.cpp4.3 fatiguedetect.cpp5 资源下载1 前言 在Ubuntu18.04实现的一个人眼监测小程序&#xff0c;使用Qt5.14、Dlib…

仿京东放大镜效果的实现

仿京东放大镜 &#xff08;1&#xff09; 整个案例可以分为三个功能模块 &#xff08;2&#xff09; 鼠标经过小图片盒子&#xff0c; 黄色的遮挡层 和 大图片盒子显示&#xff0c;离开隐藏2个盒子功能 &#xff08;3&#xff09;黄色的遮挡层跟随鼠标功能。 &#xff08;4&…

百度文心一言与Notion的比较(机器人通信的例子)

文心一言出来有一段时间了&#xff0c;也经常会去问问&#xff0c;感觉对于简单的语义理解还是可以&#xff0c;其答案对于一些常见的常识等还是可以给出不错的答案&#xff0c;但是在数学与代码等方面基本上很差&#xff0c;基本的贷款利率、微积分、没有理解语义的代码等都是…

一篇五分生信临床模型预测文章代码复现——Figure 10.机制及肿瘤免疫浸润(一)

之前讲过临床模型预测的专栏,但那只是基础版本,下面我们以自噬相关基因为例子,模仿一篇五分文章,将图和代码复现出来,学会本专栏课程,可以具备发一篇五分左右文章的水平: 本专栏目录如下: Figure 1:差异表达基因及预后基因筛选(图片仅供参考) Figure 2. 生存分析,…

C++篇 ---- 命名空间namespace

由于在c语言中在定义时可能会出现重命名现象&#xff0c;造成空间冲突&#xff0c;c语言中有命名冲突&#xff1a;1 和库冲突。2 互相之间的冲突&#xff0c;变量命名冲突。所以c中就有了对其改进的关键字namespace&#xff0c;针对重定义&#xff0c;解决空间冲突。 文章目录命…

总结820

学习目标&#xff1a; 4月&#xff08;复习完高数18讲内容&#xff0c;背诵21篇短文&#xff0c;熟词僻义300词基础词&#xff09; 学习内容&#xff1a; 高等数学&#xff1a;巩固所学&#xff0c;1~10讲内容回顾 rule No.1:never lost your knowledge. rule No.2:never f…

C++基础语法(模板)

C的模板是什么&#xff1f;有什么用&#xff1f;如果你想知道问题的答案&#xff0c;那么看这篇博客就对了&#xff0c;在这篇博客中&#xff0c;我们将探讨泛型编程&#xff0c;C模板的具体内容 目录 模板概念 函数模板 显示实例化与隐式实例化 模板不支持声明和定义分离 类模…

104.(cesium篇)cesium卫星轨道模拟

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <html lang="en"> <

【数据结构】带你细致理解八大排序

文章目录前言一.冒泡排序前一个数跟后一个数比较后一个数跟前一个数比较优化复杂度与稳定性二.插入排序初始化条件从第一个元素开始初始化条件从第二个元素开始复杂度与稳定性三.选择排序一趟选出一个最小的一趟选出一个最大的和一个最小的复杂度与稳定性四.堆排序建堆用向下调…