diff intercom/tcp.cpp @ 2:13be24d74cd2

import intercom-0.4.1
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 09:57:52 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/intercom/tcp.cpp	Fri Jun 25 09:57:52 2010 +0200
@@ -0,0 +1,132 @@
+/* tcp.cpp
+ *
+ * Copyright (C) DFS Deutsche Flugsicherung (2004, 2005). 
+ * All Rights Reserved.
+ *
+ * TCP server functions for IPv4
+ *
+ * Version 0.2
+ * adr 11sep2005 TCP client
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /* Socket io */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <netdb.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <sys/errno.h>
+#include <fcntl.h>
+
+/* error handling */
+#include <assert.h>
+
+#include <signal.h>
+
+#include "intercomd.h"
+
+int tcp_server_init(int port)
+/* open the server (listen) port - do this one time*/
+{
+  int fd = socket(PF_INET, SOCK_STREAM, 0);
+  assert_errno(fd >= 0);
+
+  struct sockaddr_in sock;
+  memset((char *) &sock, 0, sizeof(sock));
+  sock.sin_family = AF_INET;
+  sock.sin_addr.s_addr = htonl(INADDR_ANY);
+  sock.sin_port = htons(port);
+  if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
+    fprintf(stderr, "tcp_recv_init(): bind() failed\n");
+    exit(2);
+  }
+
+  int ret = listen(fd, 1);
+  assert_errno(ret >= 0);
+
+  return fd;
+}
+
+#define SA  struct sockaddr
+
+int
+socket_async(char *addr, int port) {
+/* Tcl Prozedur socket -async */
+/* in addr: Server IP-Adresse auf den gehoert wird */
+/* in port: Server TCP-Port auf den gehoert wird  */
+  struct sockaddr_in	servaddr;
+  struct hostent	*foreign_host;
+  int                   sockfd;
+  int                   flags;
+
+  /* Siehe Stevens[1998] Kap. 15.4 oder man 2 connect */
+  
+  /* init local part */
+  sockfd = socket(AF_INET, SOCK_STREAM, 0);
+  if (sockfd < 0) {
+    syslog(LOG_WARNING, "socket_async(): local socket() failed");  
+    return -1;
+  }
+  if (sockfd >= 64) {
+    syslog(LOG_WARNING, "socket_async(): local socket() sockfd >= 64");  
+    return -1;
+  }
+
+  /* init foreign part */
+  memset((char *)&servaddr, 0, sizeof(servaddr));
+
+  foreign_host = gethostbyname(addr);
+  if (foreign_host == NULL || foreign_host->h_length == 0) {
+    syslog(LOG_WARNING,     
+     "socket_async(): gethostbyname(%s) failed", 
+     addr);
+    return -1;
+  }
+  memcpy(&servaddr.sin_addr.s_addr, foreign_host->h_addr_list[0], foreign_host->h_length);
+  servaddr.sin_family = AF_INET;
+  servaddr.sin_port = htons(port);
+  
+  /* NONBLOCK */
+  flags = fcntl(sockfd, F_GETFL, 0);
+  fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+
+  if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) != 0) {
+    if (errno != EINPROGRESS) {
+      perror("tcl.c::socket_async() connect() failed");
+      return -1;
+    }
+  }
+  
+  printf("info tcp.cpp::socket_async(): host=%s IP=0x%X Port=%u\n", 
+   addr, ntohl(servaddr.sin_addr.s_addr), port);
+
+  return sockfd;
+}
+
+
+
+int tcp_server_init2(int listen_fd)
+/* open the communication (connection) - do this for every client */
+{
+  // fprintf(stderr, "tcp_server_init2\n");
+
+  // avoid blocking accept() 
+  int flags = fcntl(listen_fd, F_GETFL);
+  int ret = fcntl(listen_fd, F_SETFL, flags | O_NONBLOCK);
+  assert_errno(ret >= 0);
+
+  struct sockaddr_in sock;
+  socklen_t socklen = sizeof(sock);
+  int fd = accept(listen_fd, (struct sockaddr *) &sock, &socklen);
+  assert_errno(fd >= 0);
+
+  return fd;
+}

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.