SCTP编译运行错误及解决

在学习使用SCTP之前,你要确定操作系统是否安装了SCTP协议的相关库文件。我使用的是Ubuntu,安装方法如下:

sudo apt-get install libsctp-dev lksctp-tools

当你安装成功后,可以用如下代码来测试SCTP服务器,这是一个简单的回射服务:

sctp_darn -H 0 -P 2500 -l

然后打开另一个终端,输入下面的代码来启动一个客户端:

sctp_darn -H 0 -P 2600 -h 127.0.0.1 -p 2500 -s

安装完成后,在编译链接时,需要加上-lsctp选项。
在编写书中第十章(10.3)的SCTP服务器程序,和10.4的客户程序时,会报错。下面我们来一个一个看

问题1: “redefinition of ‘struct in_pktinof’”

意思是该结构体重定义了,原因是该结构已经包含在标准头文件“bits/in.h”中了,你只需要注释掉unp.h中的如下内容即可:

struct unp_in_pktinfo {
  struct in_addr    ipi_addr;   /* dst IPv4 address */
  int               ipi_ifindex;/* received interface index */
};

问题2:”undefined reference to ‘Sctp_recvmsg’ and ‘Sctp_sendmsg’”

这两个函数都是作者编写的包裹函数,他们并不在“unpv13e/lib”中,在unp.h中也没有声明,也就说他们没有被编译到库libunp.a中。有关sctp的相关函数在文件夹unpv13e/sctp中,将文件“sctp_addr_to_associd.c 、sctp_getnostrm.c、sctp_wrapper.c”复制到你自己编写的程序所在目录,并将你需要用的包裹函数的声明在你的源代码中,或者unp.h中,不然会报隐式函数声明的警告。之后在编译自己的程序时加上这三个文件就好了,我以自己写的Makefile为例。我在当前目录下,写了sctpserv01.c和sctpclient01.c。Makefile文件内容如下:

#编译对象的名称
PROGS = sctpserv01 sctpclient01
#链接库
LIBS+= -lsctp -lunp
#编译参数
CFLAGS= -g
#链接需要的.o文件
OBJECT= sctp_wrapper.o sctp_getnostrm.o sctp_addr_to_associd.o
#编译器gcc
CC= gcc

all: ${PROGS}

sctpserv01: sctpserv01.o ${OBJECT}
    ${CC} ${CFLAGS} -o $@ $^ ${LIBS}

sctpclient01: sctpclient01.o ${OBJECT}
    ${CC} ${CFLAGS} -o $@ $^ ${LIBS}

sctp_wrapper: sctp_wrapper.o
    ${CC} ${CFLAGS} -o ${LIBS}

sctp_getnostrm: sctp_getnostrm.o
    ${CC} ${CFLAGS} -o ${LIBS}

sctp_addr_to_associd: sctp_addr_to_associd.o
    ${CC} ${CFLAGS} -o ${LIBS}

像这样就可以解决上面的问题了。但是在编译后,运行服务器和客户程序时,在客户端程序中输入需要回射的文本,服务器进程异常退出,并打印如下消息:

getsockopt error: Invalid argument

这就是第三个问题

问题3:getsockopt error: Invalid argument

在stackoverflow上找到了解决办法,需要对源代码进行修改,需要修改使用了函数“sctp_get_no_strms”的文件以及sctp_getnostrm.c文件,修改前后内容如下:

1、sctpserv01.c

// origin
if(sri.sinof_stream >= sctp_get_no_strms(sock_fd, (SA *)&cliaddr, len))
// after
if(sri.sinof_stream >= sctp_get_no_strms(sock_fd, (SA *)&cliaddr, len, sri))

2、sctp_getnostrm.c

// origin
    status.sstat_assoc_id = sctp_address_to_associd(sock_fd,to,tolen);
    Getsockopt(sock_fd,IPPROTO_SCTP, SCTP_STATUS,
               &status, &retsz);
// after
    status.sstat_assoc_id = sri.sinfo_assoc_id;
    Getsockopt(sock_fd, IPPROTO_SCTP, SCTP_STATUS, &status, &retsz);

修改后重新编译就好了。

猜你喜欢

转载自blog.csdn.net/YZS_L_H/article/details/69526018