Linux——服务器与客户端简单一对一通信

简介: Linux——服务器与客户端简单一对一通信

运用知识


套接字相关函数socket()、bind()、listen()、connect()、accept()、recv()、send()、select()、close()


https://blog.csdn.net/weixin_45525272/article/details/107732407


atoi


atoi (表示 ascii to integer)是把字符串转换成整型数的一个函数,应用在计算机程序和办公软件中。int atoi(const char *nptr)函数会扫描参数 nptr字符串,会跳过前面的空白字符(例如空格,tab缩进)等。如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回 0 。特别注意,该函数要求被转换的字符串是按十进制数理解的。atoi输入的字符串对应数字存在大小限制(与int类型大小有关),若其过大可能报错-1。


htons


htons是将整型变量从主机字节顺序转变成网络字节顺序, 就是整数在地址空间存储方式变为高位字节存放在内存的低地址处。


bzero()函数


原型:extern void bzero(void *s, int n);


参数说明:s 要置零的数据的起始地址;


n 要置零的数据字节个数。


用法:#include <string.h>


功能:置字节字符串s的前n个字节为零且包括‘\0’。


说明:bzero无返回值,并且使用string.h头文件,string.h曾经是posix标准的一部分,但是在POSIX.1-2001标准里面,这些函数被标记为了遗留函数而不推荐使用。在POSIX.1-2008标准里已经没有这些函数了。推荐使用memset替代bzero。


代码示例



服务器


/*************************************************************************
    > File Name: server.c
    > Author: 杨永利
    > Mail: 1795018360@qq.com 
    > Created Time: 2020年08月01日 星期六 09时57分56秒
 ************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <strings.h>
int main(int argc, char* argv[]){
    if(argc != 2){
        printf("use this main with prot\n");
        exit(1);
    }
    //第一步,创建一个服务器套接字描述附
    //AF_INET是地址族,PF_INET是协议族
    //创建服务器需要与陌生的客户端进行链接,所以不能选择地址族
    int server_socket = socket(PF_INET, SOCK_STREAM, 0);
    if(server_socket == -1){
        //创建套接字失败
        printf("socket() error!\n");
        exit(-1);
    }
    //第二步,创建一个服务器地址结构体,用来与套接字绑定并且监听这个地址上的所有访问
    struct sockaddr_in server_addr;
    //清空结构体或者类型
    //第一个参数为结构体或者类型的指针,第二个参数为你希望清空到多少个字节
    //第三个参数为这个结构体或者类型的字节大小
    memset(&server_addr, 0, sizeof(server_addr));
    //服务器的地址结构体也需要设置为地址族
    server_addr.sin_family = AF_INET;
    //端口号,我们选择动态端口号,为了方便更改端口号,以免端口号被占用
    server_addr.sin_port = htons(atoi(argv[1]));
    //INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。 一般来说,在各个系统中均定义成为0值。
    server_addr.sin_addr.s_addr = INADDR_ANY;
    //第三步,绑定套接字和地址结构体
    //第一个参数为需要绑定的网络通信套接字描述符
    //第二个参数为(struct sockaddr*)类型,但是我们创建地址都是使用sockaddr_in类型,所以需要进行一次类型的强制转换
    //第三个参数,需要我们传递结构体的大小
    //bind()返回值成功为0
    //失败返回-1
    //if对数字的判断是(是否为0值)
    //0值为false 非0值为true
    //C/C++不相信bool值,更相信0和非0
    if(bind(server_socket, (struct sockaddr*)&server_addr, sizeof server_addr)){
        printf("bind() error!\n");
        exit(-1);
    }
    //第四步,监听套接字
    if(listen(server_socket, 5)){
        printf("listen() error!\n");
        exit(-1);
    }
    //第五步,创建一个套接字用来接收新的客户端连接
    //使用accept()去等待新的客户端的连接
    //第一个参数是我们的服务器套接字
    //第二个参数为sockaddr*类型的指针(可选)
    //第三个参数为sockaddr*结构体的大小(可选)
    int client_socket;
    while(1){
        //接收新的客户端访问的网络套接字描述符
      if((client_socket = accept(server_socket, NULL, NULL)) < 0){
        printf("accept() error!\n");
        exit(1);
      }
        printf("有新的客户端连接了,他的套接字是%d\n", client_socket);
      char message[1024];
        while(1){
          //第六步
          bzero(message, sizeof(message));
            int read_len;
          if((read_len = read(client_socket, message, sizeof(message))) < 0){
            printf("read() error \n");
            exit(-1);
          }
            if(!read_len){
                printf("客户端推出了聊天\n");
                break;
            }
          printf("客户端说:%s\n", message);
          //第七步,与客户端通信
          int w_len = write(client_socket, message, strlen(message));
          if(w_len != strlen(message)){
            printf("write() error!\n");
            exit(-1);
          }
        }
    }
    //第八步
    close(client_socket);
    close(server_socket);
    return 0;
}


客户端


/*************************************************************************
    > File Name: client.c
    > Author: 杨永利
    > Mail: 1795018360@qq.com 
    > Created Time: 2020年08月01日 星期六 10时01分47秒
 ************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <strings.h>
int main(int argc, char* argv[]){
  if (argc != 3)
  {
    printf("参数错误!\n");
    return -1;
  }
  // 第一步创建网络通信套接字描述符
  int client_socket=socket(AF_INET,SOCK_STREAM,0);
  // 第二步创建服务器的地址结构体
  struct sockaddr_in server_addr;
  bzero(&server_addr,sizeof(server_addr));
  server_addr.sin_family=AF_INET;
  server_addr.sin_port=htons(atoi(argv[2]));
  server_addr.sin_addr.s_addr=inet_addr(argv[1]);
  // 第三步 连接服务器
  if (connect(client_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))==-1)
  {
    /* code */
    printf("连接服务器失败!\n");
    return -1;
  }
  printf("连接服务器成功!\n");
  char message[1024];
  bzero(message,sizeof(message));
  char buf[1024];
  printf("我是客户端,我将给服务器发送内容\n");
  printf("如果希望聊天退出,请输入q或者Q:\n");
  while(1)
  {
    printf("我发送给服务器的:\n");
    scanf("%s",buf);
    if (strlen(buf)==1)
    {
      if(buf[0] == 'q' || buf[0] == 'Q')
                break;
    }
    if(strlen(buf) != write(client_socket, buf, strlen(buf))){
            printf("write() error!\n");
            exit(-1);
        }
        if(read(client_socket, message, sizeof(message)) <= 0){
            printf("read() error!\n");
            return -1;
        }
        printf("服务器对我说:%s\n", message);
        bzero(buf, sizeof(buf));
        bzero(message, sizeof(message));
  }
  close(client_socket);
  printf("服务器关闭了!\n");
    return 0;
}
相关文章
|
6天前
|
运维 监控 Linux
服务器管理面板大盘点: 8款开源面板助你轻松管理Linux服务器
在数字化时代,服务器作为数据存储和计算的核心设备,其管理效率与安全性直接关系到业务的稳定性和可持续发展。随着技术的不断进步,开源社区涌现出众多服务器管理面板,这些工具以其强大的功能、灵活的配置和友好的用户界面,极大地简化了Linux服务器的管理工作。本文将详细介绍8款开源的服务器管理面板,包括Websoft9、宝塔、cPanel、1Panel等,旨在帮助运维人员更好地选择和使用这些工具,提升服务器管理效率。
|
15天前
|
安全 算法 Linux
Linux 服务器还有漏洞?建议使用 OpenVAS 日常检查!
在数字化时代,Linux 服务器的安全至关重要。OpenVAS 是一款优秀的开源漏洞扫描工具,可以帮助及时发现并修复服务器中的安全隐患。本文将介绍 OpenVAS 的主要功能、使用方法及应对漏洞的措施,帮助用户加强服务器安全管理,确保企业数字化安全。
36 7
|
17天前
|
监控 Ubuntu Linux
使用VSCode通过SSH远程登录阿里云Linux服务器异常崩溃
通过 VSCode 的 Remote - SSH 插件远程连接阿里云 Ubuntu 22 服务器时,会因高 CPU 使用率导致连接断开。经排查发现,VSCode 连接根目录 ".." 时会频繁调用"rg"(ripgrep)进行文件搜索,导致 CPU 负载过高。解决方法是将连接目录改为"root"(或其他具体的路径),避免不必要的文件检索,从而恢复正常连接。
|
20天前
|
缓存 Unix Linux
服务器linux!!!
本文介绍了计算机的演变历史、硬件基础知识及服务器相关知识。从电子管时代的ENIAC到冯-诺伊曼架构,再到现代计算机系统组成,详细讲解了计算机的发展历程。此外,文章还介绍了服务器的分类、品牌、硬件组成以及IDC机房的上架流程,为读者提供了全面的技术背景知识。
37 0
服务器linux!!!
|
22天前
|
人工智能 安全 Linux
|
8天前
|
人工智能 弹性计算 编解码
阿里云GPU云服务器性能、应用场景及收费标准和活动价格参考
GPU云服务器作为阿里云提供的一种高性能计算服务,通过结合GPU与CPU的计算能力,为用户在人工智能、高性能计算等领域提供了强大的支持。其具备覆盖范围广、超强计算能力、网络性能出色等优势,且计费方式灵活多样,能够满足不同用户的需求。目前用户购买阿里云gpu云服务器gn5 规格族(P100-16G)、gn6i 规格族(T4-16G)、gn6v 规格族(V100-16G)有优惠,本文为大家详细介绍阿里云gpu云服务器的相关性能及收费标准与最新活动价格情况,以供参考和选择。
|
13天前
|
机器学习/深度学习 人工智能 弹性计算
什么是阿里云GPU云服务器?GPU服务器优势、使用和租赁费用整理
阿里云GPU云服务器提供强大的GPU算力,适用于深度学习、科学计算、图形可视化和视频处理等多种场景。作为亚太领先的云服务提供商,阿里云的GPU云服务器具备灵活的资源配置、高安全性和易用性,支持多种计费模式,帮助企业高效应对计算密集型任务。
|
15天前
|
存储 分布式计算 固态存储
阿里云2核16G、4核32G、8核64G配置云服务器租用收费标准与活动价格参考
2核16G、8核64G、4核32G配置的云服务器处理器与内存比为1:8,这种配比的云服务器一般适用于数据分析与挖掘,Hadoop、Spark集群和数据库,缓存等内存密集型场景,因此,多为企业级用户选择。目前2核16G配置按量收费最低收费标准为0.54元/小时,按月租用标准收费标准为260.44元/1个月。4核32G配置的阿里云服务器按量收费标准最低为1.08元/小时,按月租用标准收费标准为520.88元/1个月。8核64G配置的阿里云服务器按量收费标准最低为2.17元/小时,按月租用标准收费标准为1041.77元/1个月。本文介绍这些配置的最新租用收费标准与活动价格情况,以供参考。
|
13天前
|
机器学习/深度学习 人工智能 弹性计算
阿里云GPU服务器全解析_GPU价格收费标准_GPU优势和使用说明
阿里云GPU云服务器提供强大的GPU算力,适用于深度学习、科学计算、图形可视化和视频处理等场景。作为亚太领先的云服务商,阿里云GPU云服务器具备高灵活性、易用性、容灾备份、安全性和成本效益,支持多种实例规格,满足不同业务需求。
|
21天前
|
弹性计算
阿里云2核16G服务器多少钱一年?亲测价格查询1个月和1小时收费标准
阿里云2核16G服务器提供多种ECS实例规格,内存型r8i实例1年6折优惠价为1901元,按月收费334.19元,按小时收费0.696221元。更多规格及详细报价请访问阿里云ECS页面。
57 9
下一篇
无影云桌面