1 #define _GNU_SOURCE 1
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <unistd.h>
8 #include <fcntl.h>
9 #include <netinet/in.h>
10 #include <netinet/ip.h>
11 #include <netinet/tcp.h>
12 #include <arpa/inet.h>
13 #include <poll.h>
14
15
main(int argc,char * argv[])16 int main(int argc, char *argv[]) {
17 int sk, err, opt;
18 int port;
19 struct in_addr addr;
20 struct sockaddr_in saddr;
21 struct linger linger_opt;
22 struct pollfd polls[1];
23 if (argc!=3) {
24 printf("usage %s <ip> <port>\n", argv[0]);
25 return 1;
26 }
27 port = atoi(argv[2]); if (port<=0) {
28 printf("invalid port %s\n", argv[2]);
29 return 1;
30 }
31 if (inet_aton(argv[1], &addr) == 0) {
32 printf("invalie ip addr %s\n", argv[1]);
33 return 1;
34 }
35
36 sk = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
37 err = fcntl(sk, F_SETFL, O_RDONLY|O_NONBLOCK);
38 if (err<0) { perror("fail to fcntl"); return 1; }
39 opt=1;
40 err = setsockopt(sk, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt));
41 if (err<0) { perror("fail to set socke opt nodelay to 1"); return 1; }
42 opt=0;
43 err = setsockopt(sk, SOL_TCP, TCP_QUICKACK, &opt, sizeof(opt));
44 if (err<0) { perror("fail to set socke opt quickact to 0"); return 1; }
45 saddr.sin_family = AF_INET;
46 saddr.sin_port = htons(port);
47 saddr.sin_addr = addr;
48 connect(sk, &saddr, sizeof(saddr)); // non blocking, would reaturn -1
49 polls[0].fd=sk;
50 polls[0].events = POLLIN|POLLOUT|POLLRDHUP;
51 err = poll(polls, 1, 1000);
52 linger_opt.l_onoff=1;
53 linger_opt.l_linger=0;
54 setsockopt(sk, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(linger_opt));
55 close(sk);
56 if (err>0&&polls[0].revents==POLLOUT) printf("remote port active\n");
57 else { printf("remote port not active\n"); return 1; }
58 return 0;
59 }
60