Esempio n. 1
0
int TCPSocket::CreateTCPServer() {
	sprintf(Message, "Server: Initiating TCP Server...\n");
	easyLog("bold");
	addrinfo *ai;
	if (AppStat)
		FlushAll();
	if ((ai = GetAddrInfo()) == NULL)
		return 1; //Error On Getting Address Information
	if ((mySocketFD = GetBind(ai)) == -1)
		return 2; //Error On Binding Socket
	if (SocketBlockingMode())
		return 3;
	if (ListenOn() == -1)
		return 4; //Error On Listener
	sprintf(Message, "Server Ready: TCP Connection Management started...\n");
	easyLog("bold");
	AppStat = true;
	ManageConnections();
	return 0;
}
Esempio n. 2
0
EipStatus
NetworkHandlerInitialize(void)
{
#ifdef WIN32
	WORD wVersionRequested;
	WSADATA wsaData;
	wVersionRequested = MAKEWORD(2, 2);
	WSAStartup(wVersionRequested, &wsaData);
#endif

	/* clear the master an temp sets                                            */
	FD_ZERO(&master);
	FD_ZERO(&read_fds);

	/* create a new TCP socket */
	if ((g_network_status.tcp_listener = socket(PF_INET, SOCK_STREAM, 0)) == -1)
	{
		OPENER_TRACE_ERR("error allocating socket stream listener, %d\n", errno);
		return kEipStatusError;
	}

	int nOptVal = 1;
	if (setsockopt(g_network_status.tcp_listener, SOL_SOCKET, SO_REUSEADDR,
		(char *)&nOptVal, sizeof(nOptVal)) == -1)
	{
		OPENER_TRACE_ERR("error setting socket option SO_REUSEADDR on nTCPListener\n");
		return kEipStatusError;
	}

	/* create a new UDP unicast socket */
	if ((g_network_status.udp_unicast_listener = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
	{
		OPENER_TRACE_ERR("error allocating udp listener socket, %d\n", errno);
		return kEipStatusError;
	}

	if (setsockopt(g_network_status.udp_unicast_listener, SOL_SOCKET, SO_REUSEADDR,
		(char *)&nOptVal, sizeof(nOptVal)) == -1)
	{
		OPENER_TRACE_ERR("error setting socket option SO_REUSEADDR on nUDPListener\n");
		return kEipStatusError;
	}

	/* create a new UDP broadcast socket */
	if ((g_network_status.udp_broadcast_listener = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
	{
		OPENER_TRACE_ERR("error allocating udp listener socket, %d\n", errno);
		return kEipStatusError;
	}

	if (setsockopt(g_network_status.udp_broadcast_listener, SOL_SOCKET, SO_REUSEADDR,
		(char *)&nOptVal, sizeof(nOptVal)) == -1)
	{
		OPENER_TRACE_ERR("error setting socket option SO_REUSEADDR on nUDPListener\n");
		return kEipStatusError;
	}

	/* set up unicast udp socket */
	struct sockaddr_in unicast_address = { 
		.sin_family = AF_INET,
		.sin_port = htons(kOpenerEthernetPort),
		.sin_addr.s_addr = interface_configuration_.ip_address 
	};

	if ((bind(g_network_status.udp_unicast_listener, (struct sockaddr *) &unicast_address,
		sizeof(struct sockaddr))) == -1)
	{
		int error_code = WSAGetLastError();
		OPENER_TRACE_ERR("error with udp bind: %d, %s\n", error_code, strerror(error_code));
		return kEipStatusError;
	}

	struct sockaddr_in my_address = { 
		.sin_family = AF_INET, 
		.sin_port = htons(kOpenerEthernetPort), 
		.sin_addr.s_addr = htonl(INADDR_ANY)
	};

  /* bind the new socket to port 0xAF12 (CIP) */
  if ((bind(g_network_status.tcp_listener, (struct sockaddr *) &my_address,
      sizeof(struct sockaddr))) == -1)
    {
      OPENER_TRACE_ERR("error with bind: %s\n", strerror(errno));
      return kEipStatusError;
    }

  /* enable the udp socket to receive broadcast messages*/
  int y = 1;
  if (0
      > setsockopt(g_network_status.udp_broadcast_listener, SOL_SOCKET, SO_BROADCAST, (char *)&y,
          sizeof(int)))
    {
      OPENER_TRACE_ERR("error with setting broadcast receive for udp socket: %s\n", strerror(errno));
      return kEipStatusError;
    }

  if ((bind(g_network_status.udp_broadcast_listener, (struct sockaddr *) &my_address,
      sizeof(struct sockaddr))) == -1)
    {
      OPENER_TRACE_ERR("error with udp bind: %s\n", strerror(errno));
      return kEipStatusError;
    }

  /* switch socket in listen mode */
  if ((listen(g_network_status.tcp_listener, MAX_NO_OF_TCP_SOCKETS)) == -1)
    {
      OPENER_TRACE_ERR("networkhandler: error with listen: %s\n", strerror(errno));
      return kEipStatusError;
    }

  /* add the listener socket to the master set */
  FD_SET(g_network_status.tcp_listener, &master);
  FD_SET(g_network_status.udp_broadcast_listener, &master);
  FD_SET(g_network_status.udp_unicast_listener, &master);

  /* keep track of the biggest file descriptor */
  fdmax = GetMaxSocket(g_network_status.tcp_listener, g_network_status.udp_unicast_listener, g_network_status.udp_broadcast_listener, -1);
  last_time = GetMilliSeconds(); /* initialize time keeping */
  g_network_status.elapsed_time = 0;

  return kEipStatusOk;
}

EipStatus
NetworkHandlerProcessOnce(void)
{
  int fd;
  int res;

  read_fds = master;

  time_value.tv_sec = 0;
  time_value.tv_usec = (
      g_network_status.elapsed_time < kOpenerTimerTickInMilliSeconds ? kOpenerTimerTickInMilliSeconds
          - g_network_status.elapsed_time :
          0) * 1000; /* 10 ms */

  res = select(fdmax + 1, &read_fds, 0, 0, &time_value);

  if (res == -1)
    {
      if (EINTR == errno) /* we have somehow been interrupted. The default behavior is to go back into the select loop. */
        {
          return kEipStatusOk;
        }
      else
        {
          OPENER_TRACE_ERR("networkhandler: error with select: %s\n", strerror(errno));
          return kEipStatusError;
        }
    }

  if (res > 0)
    {

      CheckAndHandleTcpListenerSocket();
      CheckAndHandleUdpBroadCastSocket();
	  CheckAndHandleUdpUnicastSocket();
      CheckAndHandleConsumingUdpSockets();

      for (fd = 0; fd <= fdmax; fd++)
        {
          if (true == checkSocketSet(fd))
            {
              /* if it is still checked it is a TCP receive */
              if (kEipStatusError == handleDataOnTCPSocket(fd)) /* if error */
                {
                  CloseSocket(fd);
                  CloseSession(fd); /* clean up session and close the socket */
                }
            }
        }
    }

  actual_time = GetMilliSeconds();
  g_network_status.elapsed_time += actual_time - last_time;
  last_time = actual_time;

  /* check if we had been not able to update the connection manager for several OPENER_TIMER_TICK.
   * This should compensate the jitter of the windows timer
   */
  while (g_network_status.elapsed_time >= kOpenerTimerTickInMilliSeconds)
    {
      /* call manage_connections() in connection manager every OPENER_TIMER_TICK ms */
      ManageConnections();
      g_network_status.elapsed_time -= kOpenerTimerTickInMilliSeconds;
    }
  return kEipStatusOk;
}