网络编程:TCP

一、tcp编程

注意

1.数据本身有顺序
2.发送和接收次数不需要对应
3. 


 1.  C/S 模式 

==》服务器/客户端模型

server:socket()-->bind()--->listen()-->accept()-->recv()-->close()
client:socket()-->connect()-->send()-->close();

int on = 1;
setsockopt(listfd, SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));

2. 服务器端

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

1)socket() 

int socket(int domain, int type, int protocol);
功能:程序向内核提出创建一个基于内存的套接字描述符

参数:domain  地址族,PF_INET == AF_INET ==>互联网程序
                                       PF_UNIX == AF_UNIX ==>单机程序

          type    套接字类型:
                SOCK_STREAM  流式套接字 ===》TCP   
                SOCK_DGRAM   用户数据报套接字===>UDP
                SOCK_RAW     原始套接字  ===》IP

          protocol 协议 ==》0 表示自动适应应用层协议

返回值:成功 返回申请的套接字id
              失败  -1;

2)bind()

int bind(int sockfd, struct sockaddr *my_addrsocklen_t addrlen);
功能:如果该函数在服务器端调用,则表示将 参数1相关的文件描述符文件 与参数2指定的接口地址关联,用于从该接口接受数据

           如果该函数在客户端调用,则表示要将 数据从参数1所在的描述符中 取出 并从 参数2所在的接口设备上 发送出去

注意:如果是客户端,则该函数可以省略,由默认接口发送数据。
参数:sockfd 之前通过socket函数创建的文件描述符,套接字id
           my_addr 是物理接口的结构体指针。表示该接口的信息

      struct sockaddr      通用地址结构
      {
          u_short sa_family;  地址族
          char sa_data[14];   地址信息
      };

      转换成网络地址结构如下:
      struct _sockaddr_in    ///网络地址结构
      {
          u_short           sin_family; 地址族
          u_short           sin_port;   ///地址端口
          struct in_addr  sin_addr;   ///地址IP
          char               sin_zero[8]; 占位
      };

      struct in_addr
      {
          in_addr_t s_addr;
      }

      socklen_t addrlen: 参数2 的长度。
返回值:成功  0 
              失败  -1; 

3)listen()

int listen(int sockfd, int backlog);
功能:在参数1所在的套接字id上监听等待链接。
参数:sockfd  套接字id
           backlog 允许链接的个数
返回值:成功  0
              失败  -1;

4)accept()

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
   功能:从已经监听到的队列中取出有效的客户端链接并接入到当前程序。
   参数:sockfd 套接字id
              addr  如果该值为NULL ,表示不论客户端是谁都接入
                如果要获取客户端信息,则事先定义变量并传入变量地址,函数执行完毕将会将客户端
                信息存储到该变量中。

             addrlen  参数2的长度,如果参数2为NULL,则该值也为NULL
                                                   如果参数不是NULL,&len,
                                                   一定要写成len = sizeof(struct sockaddr);

   返回值:成功 返回一个用于通信的新套接字id;
                从该代码之后所有通信都基于该id

                 失败  -1;

5)接收函数/发送函数   

    read()/write ()   ///通用文件读写,可以操作套接字。
    recv(,0) /send(,0)   ///TCP 常用套机字读写
    recvfrom()/sendto() ///UDP 常用套接字读写
ssize_t recv(int sockfd, void *buf, size_t len,int flags);
功能:从指定的sockfd套接字中以flags方式获取长度为len字节的数据到指定的buff内存中。
参数:sockfd  如果服务器则是accept的返回值的新fd
                       如果客户端则是socket的返回值旧fd

          buff 用来存储数据的本地内存,一般是数组或者动态内存
          len 要获取的数据长度
          flags 获取数据的方式,0 表示阻塞接受

返回值:成功 表示接受的数据长度,一般小于等于len
              失败  -1;

6)close()

 ===>关闭指定的套接字id;

3. 客户端

1)connect()

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
   功能:该函数固定有客户端使用,表示从当前主机向目标主机发起链接请求。
   参数:sockfd 本地socket创建的套接子id
              addr 远程目标主机的地址信息
              addrlen 参数2的长度
   返回值:成功 0
                 失败 -1;

2)send()

int send(int sockfd, const void *msgsize_t len, int flags);
   功能:从msg所在的内存中获取长度为len的数据以flags方式写入到sockfd对应的套接字中。

   参数:sockfd 如果是服务器则是accept的返回值新fd
                         如果是客户端则是sockfd的返回值旧fd

              msg 要发送的消息
              len 要发送的消息长度
              flags 消息的发送方式

  返回值:成功  发送的字符长度
                失败  -1;


ser.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <time.h>
typedef struct sockaddr* (SA);
int main(int argc, char *argv[])
{
   
    //监听套接字
    int listfd =  socket(AF_INET,SOCK_STREAM, 0);
    if(-1 == listfd)
    {
        perror("socket");
        exit(1);
    }

    struct sockaddr_in ser,cli;
    bzero(&ser,sizeof(ser));
    bzero(&cli,sizeof(cli));
    ser.sin_family = AF_INET;
    ser.sin_port = htons(50000);
    //host to net long 
    ser.sin_addr.s_addr = htonl(INADDR_ANY);

    int ret = bind(listfd,(SA)&ser,sizeof(ser));
    if(-1 == ret)
    {
        perror("bind");
        exit(1);
    }
    //同一时刻三次握手排队数
    listen(listfd,3);
    socklen_t  len = sizeof(cli);
    //通信套接字 
    int conn = accept(listfd,(SA)&cli,&len);
    if(-1 == conn)
    {
        perror("accept");
        exit(1);
    }

    while(1)
    {
        char buf[512]={0};
        int rd_ret = recv(conn,buf,sizeof(buf),0);
        if(rd_ret<=0)
        {// 0  对方断开连接 -1 错误
            break;
        }
        time_t tm;
        time(&tm);
        sprintf(buf,"%s %s",buf,ctime(&tm));
        send(conn,buf,strlen(buf),0);
        
    }
    close(listfd);
    close(conn);
    return 0;
}

cli.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <time.h>
#include <arpa/inet.h>
typedef struct sockaddr* (SA);

int main(int argc, char *argv[])
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(-1 == sockfd)
    {
        perror("socket");
        exit(1);
    }
    struct sockaddr_in ser;
    bzero(&ser,sizeof(ser));
    ser.sin_family = AF_INET;
    ser.sin_port = htons(50000);
    //host to net long 
    ser.sin_addr.s_addr = inet_addr("127.0.0.1");

    int ret = connect(sockfd,(SA)&ser,sizeof(ser));
    if(-1 == ret)
    {
        perror("connect");
        exit(1);
    }
    while(1)
    {
        char buf[512]="hello,this is tcp test";
        send(sockfd,buf,strlen(buf),0);
        bzero(buf,sizeof(buf));
        recv(sockfd,buf,sizeof(buf),0);
        printf("buf :%s\n",buf);
        sleep(1);
    }
    close(sockfd);
    return 0;
}


 tcp发文件,图片——cp 1.png 2.png

ser.c 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
typedef struct sockaddr* (SA);
int main(int argc, char *argv[])
{
   
    //监听套接字
    int listfd =  socket(AF_INET,SOCK_STREAM, 0);
    if(-1 == listfd)
    {
        perror("socket");
        exit(1);
    }

    struct sockaddr_in ser,cli;
    bzero(&ser,sizeof(ser));
    bzero(&cli,sizeof(cli));
    ser.sin_family = AF_INET;
    ser.sin_port = htons(50000);
    //host to net long 
    ser.sin_addr.s_addr = htonl(INADDR_ANY);

    int ret = bind(listfd,(SA)&ser,sizeof(ser));
    if(-1 == ret)
    {
        perror("bind");
        exit(1);
    }
    //同一时刻三次握手排队数
    listen(listfd,3);
    socklen_t  len = sizeof(cli);
    //通信套接字 
    int conn = accept(listfd,(SA)&cli,&len);
    if(-1 == conn)
    {
        perror("accept");
        exit(1);
    }
    int fd = open("2.png",O_WRONLY|O_CREAT|O_TRUNC,0666);
    if(-1 ==fd)
    {
        perror("open");
        exit(1);
    }
    while(1)
    {
        char buf[512]={0};
        int rd_ret = recv(conn,buf,sizeof(buf),0);
        if(rd_ret<=0)
        {// 0  对方断开连接 -1 错误
            break;
        }
        write(fd,buf,rd_ret);
        bzero(buf,sizeof(buf)); 
        strcpy(buf,"123");
        send(conn,buf,strlen(buf),0);
        
    }
    close(fd);
    close(listfd);
    close(conn);
    return 0;
}

cli.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <time.h>
#include <arpa/inet.h>
#include <fcntl.h>
typedef struct sockaddr* (SA);

int main(int argc, char *argv[])
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(-1 == sockfd)
    {
        perror("socket");
        exit(1);
    }
    struct sockaddr_in ser;
    bzero(&ser,sizeof(ser));
    ser.sin_family = AF_INET;
    ser.sin_port = htons(50000);
    //host to net long 
    ser.sin_addr.s_addr = inet_addr("127.0.0.1");

    int ret = connect(sockfd,(SA)&ser,sizeof(ser));
    if(-1 == ret)
    {
        perror("connect");
        exit(1);
    }
    int fd = open("/home/linux/1.png",O_RDONLY);
    if(-1 ==fd)
    {
        perror("open");
        exit(1);
    }
    while(1)
    {
        char buf[512]={0};
        int rd_ret = read(fd,buf,sizeof(buf));
        if(rd_ret<=0)
        {
            break;
        }
        send(sockfd,buf,rd_ret,0);
        bzero(buf,sizeof(buf));
        recv(sockfd,buf,sizeof(buf),0);
    }
    close(fd);
    close(sockfd);
    return 0;
}

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

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

相关文章

SpringBoot日常:@Scheduled实现服务启动时执行一次

文章目录 一、Scheduled详解二、逻辑实现1、创建定时任务逻辑方法2、新建一个启动执行类 三、测试结果 说到定时任务&#xff0c;我们应该会想起Scheduled&#xff0c;Quartz以及XXL-JOB&#xff0c;但是有的单体服务或者小项目&#xff0c;为了方便快捷&#xff0c;可能会直接…

哪个充电宝口碑比较好?怎么选充电宝?2024年口碑优秀充电宝推荐

在如今快节奏的生活中&#xff0c;充电宝已然成为我们日常生活中的必备品。然而&#xff0c;市场上充电宝品牌众多&#xff0c;质量参差不齐&#xff0c;如何选择一款安全、可靠且口碑优秀的充电宝成为了消费者关注的焦点。安全性能不仅关系到充电宝的使用寿命&#xff0c;更关…

Labview_Note_4

1.字符串显示控件设置自动在最下边位置 字符串属性节点中→文本→滚动条位置 滚动框在滚动条中的位置。 如需设置该位置&#xff0c;可连线用于表示滚动行数的数值至该属性。LabVIEW在滚动条的最后一行显示连线至该属性的数值。如需滚动至文本的最后一行&#xff0c;可连线行…

springboot会议室管理系统-计算机毕业设计源码50331

目 录 摘要 1 绪论 1.1 开发背景与意义 1.2国内外研究现状 1.3 相关技术、工具简介 1.3.1 MySQL数据库的介绍 1.3.2 B/S架构的介绍 1.3.3 Java语言 1.3.4 SpringBoot框架 1.4论文结构与章节安排 2 会议室管理系统需求分析 2.1 可行性分析 2.1.1 技术可行性分析 2…

看完这些内幕 你还会夹娃娃吗?

文&#xff5c;琥珀食酒社 作者 | 朱珀 听我一句劝 别再去抓娃娃了 因为你能抓多少 早已经被设计好了 只有娃娃机老板 才能爆赚80% 今天的这篇文章 来自粉丝阿凯的投稿 他不仅能让你创业避坑 还会告诉你 整个娃娃机行业的内幕 如此敢自揭行业内幕的老板 不是对这…

SpringCloud-consul

SpringCloud-consul 1. consul介绍1.1 为什么要引入服务注册中心&#xff1f;1.2 什么是consul&#xff1f;1.3 consul能干什么1.3.1 服务发现1.3.2 健康监测1.3.3 KV存储1.3.4 多数据中心1.3.5 可视化Web界面 2. consul下载、查看版本和启动1.3.1 consul下载1.3.2 consul查看版…

2024建博会|博联AI大模型全屋智能引领智能体验新纪元

7月8日&#xff0c;2024中国建博会&#xff08;广州&#xff09;在广交会展馆及保利世贸博览馆盛大启幕。BroadLink博联智能携AI大模型全屋智能以及AI商业照明解决方案惊喜亮相&#xff0c;全方位展示AI大模型在智能家居领域的前沿应用成果。 本次建博会&#xff0c;博联智能带…

3款ui设计师必备的高效软件,一定要收藏!

UI设计小伙伴们&#xff0c;你们是否在寻找那些能够让设计工作事半功倍的插件呢&#xff1f;今天&#xff0c;我要为大家带来3款UI设计软件中的高效软件&#xff0c;它们不仅能够极大提升我们的工作效率&#xff0c;还能让我们的设计更加专业和精致。让我们一起来看看这些不容错…

HTML CSS 基础复习笔记 - 框架、装饰、弹性盒子

自己复习前端基础&#xff0c;仅用于记忆&#xff0c;初学者不太适合 示例代码 - HTML <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initi…

数据结构 —— Dijkstra算法

数据结构 —— Dijkstra算法 Dijkstra算法划分集合模拟过程打印路径 在上次的博客中&#xff0c;我们解决了使用最小的边让各个顶点连通&#xff08;最小生成树&#xff09; 这次我们要解决的问题是现在有一个图&#xff0c;我们要找到一条路&#xff0c;使得从一个顶点到另一个…

前端JS特效第26波:jQuery日期时间选择器插件

jQuery日期时间选择器插件&#xff0c;先来看看效果&#xff1a; 部分核心的代码如下&#xff1a; <!DOCTYPE html> <html> <head lang"zh-CN"> <meta charset"UTF-8"> <title>jQuery日期时间选择器插件 - PHP中文网</t…

UI自动化测试是什么?什么项目适合做UI自动化测试

1. 页面对象设计模式的优势 (1) 创建可以跨多个测试用例共享的代码 (2) 减少代码的重复性 (3) 如果界面需要维护&#xff0c;只需要修改一个地方&#xff0c;修改以及维护的成本减少 2. 每个目录结构表达的意思 (1) Base:基础层&#xff0c;是用来编写定位元素 (2) Commo…

PL/SQL安装+汉化教程

PL/SQL安装教程 一、安装&#xff1a; 登陆官网&#xff1a;PL/SQL Developer - Allround Automations下载 下载PL/SQL稳定版本12.0.7 根据自己计算机版本安装相适配的版本。我这里安装X64-bit版本 进行安装&#xff1a; 根据情况去更改安装&#xff0c;我这里全部下一步…

【从零到一,如何搭建本地AI大模型】

摘要: 本文主要记录这一段时间对本地大模型搭建的心得。 作为一个资深程序员,在AI席卷全球的时候,深深感觉到了一丝危机感,不禁有一个想法不断在脑海闪现:我会不会真的哪一天被AI给取代了? 从哪入手 程序员出生的我,掌握了很多语言,从前端到数据库,再到运维,基本都…

Java基础-组件及事件处理(上)

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 Swing 概述 MVC 架构 Swing 特点 控件 SWING UI 元素 JFrame SWING 容器 说明 常用方法 示例&a…

为什么选择虚拟艺术设计展览?艺术家应知的五个关键好处

随着技术的进步&#xff0c;虚拟艺术设计展览成为了展示艺术作品的重要途径。它不仅为艺术家们提供了新的展示平台&#xff0c;还打破了传统展览的局限。 1、扩大观众范围&#xff1a;打破地理限制 虚拟艺术设计展览能够打破地理限制&#xff0c;使得全球观众可以随时随地访问…

Androidstudio开发,天气预报APP

1.项目功能思维导图 2. 项目涉及到的技术点 数据来源&#xff1a;和风天气API使用okhttp网络请求框架获取api数据使用gson库解析json数据使用RecyclerViewadapter实现未来7天列表展示和天气指数使用PopupMenu 实现弹出选项框使用动画定时器实现欢迎页倒计时和logo动画使用Text…

《梦醒蝶飞:释放Excel函数与公式的力量》10.2 COMPLEX函数

第二节 10.2 COMPLEX函数 10.2.1函数简介 COMPLEX函数是Excel中的一个工程函数&#xff0c;用于将实部和虚部组合成一个复数。复数广泛应用于工程、电气、物理等领域&#xff0c;COMPLEX函数提供了方便的复数表示和计算方法。 10.2.2语法&#xff1a; COMPLEX(real_num, i_…

SpringSecurity-SpirngBoot-方法级授权(SpringSecurity6.3新特性)(四)

SpringSecurity-SpirngBoot-方法级授权&#xff08;SpringSecurity6.3新特性&#xff09;&#xff08;四&#xff09; 本章使用SpringSecurity6.3新特性实现数据级别的鉴权&#xff0c;主要的目的是实现不同权限的用户查询同一个方法&#xff0c;限制一些内容只能拥有特定权限…

自定义@AnonymousAccess注解

一.目的&#xff1a; 自定义AnonymousAccess注解&#xff0c;可以直接在controller上添加该注解使请求绕过权限验证进行匿名访问&#xff0c;便于快速调用调试以及部分不需要进行安全验证的接口。而不是每次都需要去SecurityConfig文件中进行修改。 二.流程&#xff1a; 三.实…