2
|
1 /* tcp.cpp
|
|
2 *
|
|
3 * Copyright (C) DFS Deutsche Flugsicherung (2004, 2005).
|
|
4 * All Rights Reserved.
|
|
5 *
|
|
6 * TCP server functions for IPv4
|
|
7 *
|
|
8 * Version 0.2
|
|
9 * adr 11sep2005 TCP client
|
|
10 */
|
|
11
|
|
12
|
|
13 #include <stdio.h>
|
|
14 #include <stdlib.h>
|
|
15 #include <string.h>
|
|
16
|
|
17 /* Socket io */
|
|
18 #include <sys/socket.h>
|
|
19 #include <netinet/in.h>
|
|
20 #include <netinet/tcp.h>
|
|
21 #include <assert.h>
|
|
22 #include <sys/types.h>
|
|
23 #include <netdb.h>
|
|
24 #include <sys/time.h>
|
|
25 #include <unistd.h>
|
|
26 #include <sys/errno.h>
|
|
27 #include <fcntl.h>
|
|
28
|
|
29 /* error handling */
|
|
30 #include <assert.h>
|
|
31
|
|
32 #include <signal.h>
|
|
33
|
|
34 #include "intercomd.h"
|
|
35
|
|
36 int tcp_server_init(int port)
|
|
37 /* open the server (listen) port - do this one time*/
|
|
38 {
|
|
39 int fd = socket(PF_INET, SOCK_STREAM, 0);
|
|
40 assert_errno(fd >= 0);
|
|
41
|
|
42 struct sockaddr_in sock;
|
|
43 memset((char *) &sock, 0, sizeof(sock));
|
|
44 sock.sin_family = AF_INET;
|
|
45 sock.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
46 sock.sin_port = htons(port);
|
|
47 if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
|
|
48 fprintf(stderr, "tcp_recv_init(): bind() failed\n");
|
|
49 exit(2);
|
|
50 }
|
|
51
|
|
52 int ret = listen(fd, 1);
|
|
53 assert_errno(ret >= 0);
|
|
54
|
|
55 return fd;
|
|
56 }
|
|
57
|
|
58 #define SA struct sockaddr
|
|
59
|
|
60 int
|
|
61 socket_async(char *addr, int port) {
|
|
62 /* Tcl Prozedur socket -async */
|
|
63 /* in addr: Server IP-Adresse auf den gehoert wird */
|
|
64 /* in port: Server TCP-Port auf den gehoert wird */
|
|
65 struct sockaddr_in servaddr;
|
|
66 struct hostent *foreign_host;
|
|
67 int sockfd;
|
|
68 int flags;
|
|
69
|
|
70 /* Siehe Stevens[1998] Kap. 15.4 oder man 2 connect */
|
|
71
|
|
72 /* init local part */
|
|
73 sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
74 if (sockfd < 0) {
|
|
75 syslog(LOG_WARNING, "socket_async(): local socket() failed");
|
|
76 return -1;
|
|
77 }
|
|
78 if (sockfd >= 64) {
|
|
79 syslog(LOG_WARNING, "socket_async(): local socket() sockfd >= 64");
|
|
80 return -1;
|
|
81 }
|
|
82
|
|
83 /* init foreign part */
|
|
84 memset((char *)&servaddr, 0, sizeof(servaddr));
|
|
85
|
|
86 foreign_host = gethostbyname(addr);
|
|
87 if (foreign_host == NULL || foreign_host->h_length == 0) {
|
|
88 syslog(LOG_WARNING,
|
|
89 "socket_async(): gethostbyname(%s) failed",
|
|
90 addr);
|
|
91 return -1;
|
|
92 }
|
|
93 memcpy(&servaddr.sin_addr.s_addr, foreign_host->h_addr_list[0], foreign_host->h_length);
|
|
94 servaddr.sin_family = AF_INET;
|
|
95 servaddr.sin_port = htons(port);
|
|
96
|
|
97 /* NONBLOCK */
|
|
98 flags = fcntl(sockfd, F_GETFL, 0);
|
|
99 fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
|
100
|
|
101 if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) != 0) {
|
|
102 if (errno != EINPROGRESS) {
|
|
103 perror("tcl.c::socket_async() connect() failed");
|
|
104 return -1;
|
|
105 }
|
|
106 }
|
|
107
|
|
108 printf("info tcp.cpp::socket_async(): host=%s IP=0x%X Port=%u\n",
|
|
109 addr, ntohl(servaddr.sin_addr.s_addr), port);
|
|
110
|
|
111 return sockfd;
|
|
112 }
|
|
113
|
|
114
|
|
115
|
|
116 int tcp_server_init2(int listen_fd)
|
|
117 /* open the communication (connection) - do this for every client */
|
|
118 {
|
|
119 // fprintf(stderr, "tcp_server_init2\n");
|
|
120
|
|
121 // avoid blocking accept()
|
|
122 int flags = fcntl(listen_fd, F_GETFL);
|
|
123 int ret = fcntl(listen_fd, F_SETFL, flags | O_NONBLOCK);
|
|
124 assert_errno(ret >= 0);
|
|
125
|
|
126 struct sockaddr_in sock;
|
|
127 socklen_t socklen = sizeof(sock);
|
|
128 int fd = accept(listen_fd, (struct sockaddr *) &sock, &socklen);
|
|
129 assert_errno(fd >= 0);
|
|
130
|
|
131 return fd;
|
|
132 }
|