第14章 高级IO函数
测试套接字超时,编译的时候遇到的问题:
gcc -o connect_timeo connect_timeo.c -lunp
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libunp.a(signal.o): In function `Signal':
/root/unpv13e/lib/signal.c:29: multiple definition of `Signal'
/tmp/cc5G0CbF.o:connect_timeo.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
使用的程序:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef void (Sigfunc)(int);
Sigfunc *Signal(int signo, Sigfunc* func)
{
struct sigaction act, oact;
act.sa_handler = func;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
if(signo == SIGALRM) {
act.sa_flags = SA_INTERRUPT;
}else {
act.sa_flags = SA_RESTART;
}
if(sigaction(signo,&act,&oact) < 0)
return SIG_ERR;
return oact.sa_handler;
}
static void connect_alarm(int signum)
{
printf("alarm time out\n");
return;
}
int connect_timeo(int sockfd, const struct sockaddr *saptr,socklen_t salen, int nsec)
{
int n;
Sigfunc *sigfunc;
sigfunc = Signal(SIGALRM,connect_alarm);
alarm(nsec);
if((n = connect(sockfd,saptr,salen)) <0) {
printf("connect error,errno=%d\n",errno);
close(sockfd);
if(errno == EINTR)
errno = ETIMEDOUT;
}
alarm(0);
signal(SIGALRM,sigfunc);
return n;
}
int main(int argc,char* argv[])
{
struct sockaddr_in sa;
struct sockaddr_in server;
int fd;
int ret;
char recv[1024];
fd = socket(AF_INET,SOCK_STREAM,0);
if(fd < 0)
printf("socket error\n");
sa.sin_family = AF_INET;
//sa.sin_port = 10000;
sa.sin_addr.s_addr = INADDR_ANY;
if(bind(fd,(struct sockaddr*)&sa,sizeof(struct sockaddr)) < 0) {
printf("bind error\n");
close(fd);
}
server.sin_family = AF_INET;
server.sin_port = htons(10000);
inet_pton(AF_INET,"1.0.0.2",&(server.sin_addr)); //--------ipaddr 1.0.0.2 must be a address not existed
//(connect(fd,(struct sockaddr*)&server, sizeof(struct sockaddr)) < 0) {
//}
ret = connect_timeo(fd,(struct sockaddr*)&server,sizeof(struct sockaddr),10);
read(fd,recv,1024);
//printf("recv=%s\n",recv);
return ret;
}
问题解决办法:
头文件设置改为:
#include "unp.h"
注释掉 “Sigfunc *Signal(int signo, Sigfunc* func)”
编译没有发现问题:
gcc -o connect_timeo connect_timeo.c -lunp
运行:
把超时时间改短
把前面的部分修改了一下,用/lib下面的connect_timeo.c替换:
--------------------------------------------------------------------------------------------------------------------
环境设置:
vs-code 环境设置
lanuch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "gcc - Build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: gcc build active file",
"miDebuggerPath": "/usr/bin/gdb"
}
]
}
task.json
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc build active file",
"command": "/usr/bin/gcc",
"args": [
"-g",
//"/root/unpv13e/connect_timeo.c",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}",
"-lunp"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}