ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
3 мая
1203408 Топик полностью
IBAH (26.04.2022 22:07, просмотров: 300) ответил Dingo на Спрошу здесь, а то на stackowerflow засмеют. Вызовы accept() select() - как их готовить? Пытаюсь сетевое на ПК делать, вопросов очень много.
Делал поделку на неблокирующих сокетах, в все в одном потоке 
--
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "Mserial.h"
#include <winsock2.h>
#include <stdbool.h>
#include "main.h"
#include "wait.h"

int main(int argc, char* argv[])
  {
  printf("*********************************************************\n");
  printf("* Connection TCP-clients COM port                       *\n");
  printf("* Call \"tcp2com.exe Port ComPort BaudRate TimOut\"       *\n");
  printf("*********************************************************\n\n");
  //загрузка параметров
  if(argc!=5){printf("Error parameter!\n");return 1;}
  //ТСР-порт
  unsigned short Port=atoi(argv[1]);
  if(Port==0){printf("Error parameter Port!\n");return 1;}
  //Скорость передачи
  int BaudRate=atoi(argv[3]);
  if(BaudRate==0){printf("Error parameter BaudRate!\n");return 1;}
  //открытие СОМ-порта
  if(!ComPortOpen(argv[2], BaudRate, Data8Bit, NonParity, OneStopBit))
    {
    printf("%s",argv[2]); printf(" can't open!\n");
    return 1;
    }
  printf("%s",argv[2]); printf(" open! BaudRate=%d\n",BaudRate);
  //Таймаут соеденения
  int TimOut=atoi(argv[4]);
  if(TimOut==0){printf("Error parameter TimOut!\n");return 1;}
  printf("Connection timeout %d\n",TimOut);


  ///////////////////////////////////////////////////////////////////////////
  //инициализируем библиотеку ТСР
  WSADATA ws;
  if (FAILED (WSAStartup (MAKEWORD( 1, 1 ), &ws) ) )
    {
    printf("Error WSAStartup()!\n");
    return 1;
    }
  /////////////////////////////////////////////////////////////////////////
  //создаем сокет
  SOCKET s;
  s = socket(AF_INET, SOCK_STREAM, 0);
  if (s==INVALID_SOCKET)
   {
   printf("Error socket()!\n");
   closesocket(s);
   WSACleanup();
   return 1;
   }

  //деблокируем  сокет
  unsigned long TmpVar = !0;
  if (SOCKET_ERROR == ioctlsocket (s, FIONBIO, &TmpVar) )
   {
   printf("Error ioctlsocket()!\n");
   closesocket(s);
   WSACleanup();
   return 1;
   }

  //создаем сервер
  struct sockaddr_in name;
  ZeroMemory (&name, sizeof (name));
  name.sin_family = AF_INET;
  name.sin_addr.S_un.S_addr = htonl (INADDR_ANY);
  name.sin_port = htons (Port);
  if (SOCKET_ERROR == bind (s, ((struct sockaddr*)(&name)), sizeof (name) ) )
    {
    printf("Error bind()!\n");
    closesocket(s);
    WSACleanup();
    return 1;
    }

  //Get the local host information
  struct hostent* localHost = gethostbyname("");
  printf ("Server IP %s",inet_ntoa (*(struct in_addr *)*localHost->h_addr_list));
  printf (":%d\n", ntohs (name.sin_port));

  //включаем сервер на прослушку
  if (SOCKET_ERROR == listen(s, 0) )
    {
    printf("Error listen()!\n");
    closesocket(s);
    WSACleanup();
    return 1;
    }

  //Алгоритм Нагла
  //char Opt=0; setsockopt(s,IPPROTO_TCP, TCP_NODELAY,&Opt,sizeof(Opt));

  ////////////////////////////////////////////////////////////////////////
  SOCKET s0;//сокет клиента
  char conekt0=0;//признак подключения сокета
  printf("\nWait connect client...\n");
  Timer_t t1s;  StartTimer(&t1s, 200);//таймер вывода звездочек
  Timer_t TimTimout;  StartTimer(&TimTimout, TimOut*1000);//таймер соединения
  int FlagInit=0;//признак инициализации сокета

  while(1)//главный цикл
    {
    //////////////////////////////////////////////////////////////////////
    //ожидаем подключения TCP
    if(conekt0==0)
      {
      if(FlagInit)//повторная инициализация сокета
        {
        s = socket(AF_INET, SOCK_STREAM, 0);
        if (s==INVALID_SOCKET)
         {
         printf("Error socket()!\n");
         closesocket(s);
         WSACleanup();
         return 1;
         }

        //деблокируем  сокет
        unsigned long TmpVar = !0;
        if (SOCKET_ERROR == ioctlsocket (s, FIONBIO, &TmpVar) )
         {
         printf("Error ioctlsocket()!\n");
         closesocket(s);
         WSACleanup();
         return 1;
         }

        //создаем сервер
        struct sockaddr_in name;
        ZeroMemory (&name, sizeof (name));
        name.sin_family = AF_INET;
        name.sin_addr.S_un.S_addr = htonl (INADDR_ANY);
        name.sin_port = htons (Port);
        if (SOCKET_ERROR == bind (s, ((struct sockaddr*)(&name)), sizeof (name) ) )
          {
          printf("Error bind()!!!!\n");
          closesocket(s);
          WSACleanup();
          return 1;
          }
        //включаем сервер на прослушку
        if (SOCKET_ERROR == listen(s, 0)) // Максимально возможное кол-во входящих соединений
          {
          printf("Error listen()!\n");
          closesocket(s);
          WSACleanup();
          return 1;
          }

        //Алгоритм Нагла
        //char Opt=!0; setsockopt(s,IPPROTO_TCP, TCP_NODELAY,&Opt,sizeof(Opt));

        FlagInit=0;
        }

      //ожидаем соединения
      struct sockaddr_in s0_adr;
      int s0_adr_len = sizeof (s0_adr);
      ZeroMemory (&s0_adr, sizeof (s0_adr));
      s0 = accept(s,(struct sockaddr*)&s0_adr, &s0_adr_len);
      if(s0 != INVALID_SOCKET)
        {
        printf ("\nConnect! ");
        printf ("Client IP: %s", inet_ntoa ((struct in_addr) s0_adr.sin_addr));
        printf (":%d\n", ntohs (s0_adr.sin_port));
        conekt0=!0;
        closesocket(s);
        StartTimer(&TimTimout, TimOut*1000);//таймер соединения
        }
      }
    //передача управления системе
    if(conekt0==0)
      {
      if(TimerReStart(&t1s))//отрисовка звездочек
        {
        putchar('*');
        static int i=0;
        if(i==60)
          {
          i=0;
          printf("\r                                                                       \r");
          }
        i++;
        }
      Sleep(1);
      }


    /////////////////////////////////////////////////////////////////////
    //режим соеденения
    if(conekt0!=0)
      {
      if(Timer(&TimTimout))
        {//истек таймаут соединения
        printf("\nConnection timeout expired\n");
        printf("\nWait connect client...\n");
        closesocket(s0);
        closesocket(s);
        conekt0=0;
        FlagInit=!0;
        continue;
        }
      char RWbuf[1];//буфер приема-передачи
      /////////////////////////////////////////////////////////////////////
      //обработка сообщений первого клиента
      char flag0=0;//флаг приема первого клиента
      int iResult0 = recv(s0, RWbuf, 1, 0); //проверяем наличие данных
      if(iResult0 == 0) //соеденение разовано
        {
        printf("\nDisconnect client!\n");
        printf("\nWait connect client...\n");
        conekt0=0;
        FlagInit=!0;
        continue;
        }
      if(iResult0 != SOCKET_ERROR) //данные есть
        {
        flag0=!0;
        ComPortPut(RWbuf[0]);
        StartTimer(&TimTimout, TimOut*1000);//таймер соединения
        }
      else
        {
        int errTCP=WSAGetLastError();
        if(errTCP==WSAECONNABORTED || errTCP==WSAECONNRESET)
          {
          //соеденение разорвано
          printf("\nDisconnect client!\n");
          printf("\nWait connect client...\n");
          FlagInit=!0;
          conekt0=0;
          continue;
          }
        if(errTCP!=WSAEWOULDBLOCK)
          {
          printf("Receive failed socket 0 with error: %d\n", WSAGetLastError());
          closesocket(s);
          WSACleanup();
          return 1;
          }
        }

      /////////////////////////////////////////////////////////////////////
      //обработка сообщений СОМ-порта
      char flag1=0;//флаг приема по СОМ-порту
      int ComPortZn=ComPortInKey16();
      if(ComPortZn != 0)
        {// данные есть
        ComPortZn=ComPortZn&0xFF;
        flag1=!0;
        int sh=0;
        while(1) //отправляем данные
          {
          StartTimer(&TimTimout, TimOut*1000);//таймер соединения
          int iResult = send( s0, (char*)(&ComPortZn), 1, 0 );
          if(iResult == SOCKET_ERROR)
            {
            if(WSAGetLastError() == WSAEWOULDBLOCK)
              {
              Sleep(MaxTimeOutTrans);
              sh++;
              if(sh>MaxTrans)
                {
                //превышен таймаут предачи
                printf("Send failed socket with error: %d\n", WSAGetLastError());
                closesocket(s);
                WSACleanup();
                return 1;
                }
              continue;//повторная передача
              }
            else
              {
              if(WSAGetLastError()==WSAECONNABORTED || WSAGetLastError()==WSAECONNRESET)
                {
                //соеденение разорвано
                printf("\nDisconnect client!\n");
                printf("\nWait connect client...\n");
                conekt0=0;
                break;
                }
              printf("Send failed-failed socket with error: %d\n", WSAGetLastError());
              closesocket(s);
              WSACleanup();
              return 1;
              }
            }
          break;
          }
        }
      ////////////////////////////////////////////////////////////////////
      //Передача управления системе в случае простоя
      if(flag0==0 && flag1==0)Sleep(1);
      }
    }
  printf("The End!\n");
  return 0;
  }




--