网络编程:TCP

news2024/9/20 18:37:36

一、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;
}

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

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

相关文章

如何学好C++?

首先&#xff0c;对于零基础的想学习C的同学&#xff0c;我想要你们先明白一件事&#xff1a;C是一门极为复杂且难以掌握的编程语言。因此推荐在学习C之前可以先去学习C语言&#xff0c;在拥有了一定的知识储备和编程能力后再学习C会更加的高效和相对轻松。 下面推荐从三个方面…

源码编译安装 LAMP

目录 2.1Apache 网站服务基础 2.1.1 Apache 简介 1.Apache 的起源 2.Apache 的主要特点 2.1.2 安装 httpd 服务器 1.准备工作 2.源码编译及安装 3.确认安装结果​编辑 4.优化执行路径 5.添加 httpd 系统服务 2.2 httpd 服务器的基本配置 2.2.1 Web 站点的部…

锅总反驳李彦宏说的“不要卷模型,要卷应用”

李彦宏的观点是大家不要卷模型&#xff0c;要卷应用&#xff0c;但我认为这种看法是荒谬的。以下是24条反驳李彦宏观点的论点和论据&#xff1a; 模型的准确性直接决定应用的质量和用户体验&#xff1a; 论据&#xff1a;在自然语言处理、计算机视觉等领域&#xff0c;模型的准…

安全求交集PSI

安全求交集定义 求交集的PSI&#xff1a;交集可以被两方看见或其中一方看见&#xff0c;非交集进行保护有两方的PSI半诚实的PSI&#xff1a;攻击者要严格遵守协议&#xff0c;在此基础上得到他人的秘密是做不到的 Two-Party Semi-Honest PSI 挑战一&#xff1a;隐藏非交集元素…

纯前端如何实现Gif暂停、倍速播放

前言 GIF 我相信大家都不会陌生&#xff0c;由于它被广泛的支持&#xff0c;所以我们一般用它来做一些简单的动画效果。一般就是设计师弄好了之后&#xff0c;把文件发给我们。然后我们就直接这样使用&#xff1a; <img src"xxx.gif"/>这样就能播放一个 GIF …

offer题目33:判断是否是二叉搜索树的后序遍历序列

题目描述&#xff1a;输入一个整数数组&#xff0c;判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。例如&#xff0c;输入数组{5,7,6,9,11,10,8},则返回true,&#xff0c;因为这个整数是下图二叉搜索树…

作业/数据结构/2024/7/8

链表的相关操作作业&#xff1a; 1】 按值修改 2】按值查找&#xff0c;返回当前节点的地址 &#xff08;先不考虑重复&#xff0c;如果有重复&#xff0c;返回第一个&#xff09; 3】 逆置(反转) 4】释放链表 main.c #include "head.h"int main(int argc, con…

6.Python学习:异常和日志

1.异常的抓取 1.1异常的概念 使用异常前&#xff1a; print(1/0)使用异常后&#xff1a;错误提示更加友好&#xff0c;不影响程序继续往下运行 try:print(10/0) except ZeroDivisionError:print("0不能作为分母")1.2异常的抓取 第一种&#xff1a;如果提前知道可…

微软清华提出全新预训练范式,指令预训练让8B模型实力暴涨!实力碾压70B模型

现在的大模型训练通常会包括两个阶段&#xff1a; 一是无监督的预训练&#xff0c;即通过因果语言建模预测下一个token生成的概率。该方法无需标注数据&#xff0c;这意味着可以利用大规模的数据学习到语言的通用特征和模式。 二是指令微调&#xff0c;即通过自然语言指令构建…

核密度估计KDE和概率密度函数PDF(深入浅出)

目录 1. 和密度估计&#xff08;KDE&#xff09;核密度估计的基本原理核密度估计的公式核密度估计的应用Python中的KDE实现示例代码 结果解释解释结果 总结 2. 概率密度函数&#xff08;PDF&#xff09;概率密度函数&#xff08;PDF&#xff09;是怎么工作的&#xff1a;用图画…

数据类型及数据块认知

西门子STEP7编程语言 梯形图(LAD) 功能块图(FBD) 语句表(STL) 其中梯形图和功能块图可以相互转换 CPU常用数据区 信号输入区 I 信号输出区 Q 程序中表现形式&#xff0c;IX.X/QX.X;IWX/QWX-访问的是CPU输出输入过程映像区 另一种形式IWX:P/QWX:P-访问的是信号端口地址&#xf…

idea推送到gitee 401错误

在idea上推送时遇到这样的问题&#xff0c;解决方法如下&#xff1a; 在https://的后面加上 用户名:密码 然后再提交就ok啦&#xff01;

285个地级市出口产品质量及技术复杂度(2011-2021年)

出口产品质量与技术复杂度&#xff1a;衡量国家竞争力的关键指标 出口产品质量是衡量国内企业生产的产品在国际市场上竞争力的重要标准。它不仅要求产品符合国际标准和目标市场的法律法规&#xff0c;而且需要保证产品质量的稳定性和可靠性。而出口技术复杂度则进一步体现了一…

Python神经模型评估微分方程图算法

&#x1f3af;要点 &#x1f3af;神经网络映射关联图 | &#x1f3af;执行时间分析 | &#x1f3af;神经网络结构降维 | &#x1f3af;量化图结构边作用 | &#x1f3af;数学评估算法实现 &#x1f36a;语言内容分比 &#x1f347;Python随机梯度下降算法 随机梯度下降是梯度…

nodejs安装配置详解

一、下载Node.js安装包 官网下载链接[点击跳转] 建议下载LTS版本&#xff08;本教程不适用于苹果电脑&#xff09; 二 、安装Node.js 2.1 下载好安装包后双击打开安装包&#xff0c;然后点击Next 2.2 勾选同意许可后点击Next 2.3 点击Change选择好安装路径后点击Next&#x…

使用微pe装系统

本文仅作为记录&#xff0c;不作为教程。 今天心血来潮想下点游戏玩玩&#xff0c;一看之前分的200gc盘已经红了&#xff0c;再加上大学之后这个笔记本已经用得很少了&#xff0c;于是打算重装电脑。 参考: 微PE辅助安装_哔哩哔哩_bilibil… 1.下载微pe和win10系统到U盘 我这…

18.按键消抖模块设计(使用状态机,独热码编码)

&#xff08;1&#xff09;设计意义&#xff1a;按键消抖主要针对的时机械弹性开关&#xff0c;当机械触点断开、闭合时&#xff0c;由于机械触点的弹性作用&#xff0c;一个按键开关在闭合时不会马上稳定地接通&#xff0c;在断开时也不会一下子就断开。因而在闭合以及断开的瞬…

Java PKI Programmer‘s Guide

一、PKI程序员指南概述 PKI Programmer’s Guide Overview Java认证路径API由一系列类和接口组成&#xff0c;用于创建、构建和验证认证路径。这些路径也被称作认证链。实现可以通过基于提供者的接口插入。 这个API基于密码服务提供者架构&#xff0c;这在《Java密码架构参考指…

Windows C++ vs2022环境中下载、安装和使用osmesa

第一步&#xff1a;安装 MinGW-w64 请参考这篇文章进行安装&#xff1a; 在Windows中安装MinGW-w64最新版本 第二步&#xff1a;安装DirectX SDK 请参考这篇文章进行安装&#xff1a; 下载安装Microsoft DirectX SDK(June 2010) 第三步&#xff1a;安装Windows SDK 请参考这篇…

数据仓库哈哈

数据仓库 基本概念数据库&#xff08;database&#xff09;和数据仓库&#xff08;Data Warehouse&#xff09;的异同 整体架构分层架构方法论ER模型&#xff08;建模理论&#xff09;维度模型 何为分层第一层&#xff1a;数据源&#xff08;ODS ER模型&#xff09;设计要点日志…