• unp.h环境搭建以及在WSL中的使用


    选到了想上的网络编程课,用的书是非常著名的Unix Networking Programming Volume 1(Edition 3),那么实验自然是用书上的实验了。书上的实验基本上都引用了unp.h的头文件,这个头文件是这本书编写的一种All in one的环境,并且在某些结构体未定义的情况下补充定义结构体等功能,该环境需要手动安装和配置,因此记录一下在配置过程,以及过程中出现的问题和解决办法。

    系统环境

    WSL2,发行版为Ubuntu 20.04LTS,其他WSL发行版以及原版Linux应该都差不多(未经过考证)

    VSCode和插件Remote WSL

    build-essential,使用apt安装

    配置过程

    1. 下载unp库的源码,下载地址

    2. 解压并进入文件夹,按照README的步骤执行以下命令

      ./configure
      
      cd lib/
      make
      
      cd ../libfree/
      make
      

      libfree/中make的时候可能会遇到size_t的报错

      解决办法是将libfree/inet_ntop.c的第60行size_t改为socklen_t即可

      在此过程中还可能会遇到一些warning,可能是因为使用的gcc-9和比较高版本的内核,和这个库有一点不太兼容,只要没有error就可以执行

    3. make完成回到主目录下,发现已经编译好静态库libunp.a,将其复制到/usr/lib/usr/lib64两个目录下,再将config.hkey/unp.h复制到/usr/include/unp目录下(这里我新建了unp的目录为了方便管理,也可以直接放在/usr/include目录下),并将unp.h中的#include "../config.h"改为#include "config.h"(只要你的unp.h能找到config.h就好了)

    4. 开始使用书上的例子作为测试

      #include "unp.h"
      
      int main(int argc, char **argv) {
          int sockfd, n;
          char recvline[MAXLINE + 1];
          struct sockaddr_in servaddr;
      
          if (argc != 2) {
              err_quit("usage: a.out <IPaddress>");
          }
      
          if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
              err_sys("socket error");
          }
      
          bzero(&servaddr, sizeof(servaddr));
          servaddr.sin_family = AF_INET;
          servaddr.sin_port   = htons(13);
          if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
              err_quit("inet_pton error for %s", argv[1]);
          }
      
          if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) {
              err_sys("connect error");
          }
      
          while ((n = read(sockfd, recvline, MAXLINE)) > 0) {
              recvline[n] = 0;
              if (fputs(recvline, stdout) == EOF) {
                  err_sys("fputs error");
              }
          }
          if (n < 0) {
              err_sys("read error");
          }
      
          exit(0);
      }
      

      执行以下编译命令

      gcc cli.c -o cli -lunp
      

      可能会出现以下报错

      1. in_pktinfo重复定义

        发现是in_pktinfo的结构体重复定义了,具体的定义位置是在/usr/include/x86_64-linux-gnu/bits/in.h第157行,比较两者的定义可以发现,其中的变量名称都是相同的,那么直接替换应该没有问题,但是直接注释看上去又不太好(其实应该没问题),所以参考unp.h中的其他代码风格,在config.h中定义了一个宏#define HAVE_STRUCT_IN_PKTINFO 1,然后将unp.h中的结构体定义用#ifndef框起来,如下图

        再次编译就没有这个错误了

      2. err_syserr_print没有定义

        这是因为该函数是单独写出来的,需要下载其他文件,为了避免节外生枝,笔者直接采用printf()exit()来显示并退出

    至此,unp.h环境搭建完毕,并且直接使用VSCode的Remote WSL到连虚拟机,C语言的插件也能识别到unp库的东西

  • 相关阅读:
    String类的操作方法
    操作日期时间类 Calendar类
    JAVA中Date类的使用
    集合方法整理
    JAVA日期——java.util.date类的操作
    关于Collections的操作方法
    java中集合
    java中继承的关系
    java
    封装继承多态-java面向对象三大特征
  • 原文地址:https://www.cnblogs.com/BadCodeBuilder/p/13870485.html
Copyright © 2020-2023  润新知