Делал поделку на неблокирующих сокетах, в все в одном потоке
--
#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;
}
---
- Спасибо! - Dingo(27.04.2022 07:49)