超小型循环式服务器-原生socket编程

闲来无聊,写了一个体积很小的tcp循环式服务器,方便各系统移植。特共享如下,编译后体积约为8kB,经过7*24小时压力测试,5个以内连接都OK。

结合我之前的tcp转发程序,可以做成一个网卡端口信息扫描日志服务。


#include
#include
#include
#include


#define SERV_PORT 49999
#define MAX_BUF_ONE 65535
#define MIN_IP_SIZE 16
#define MESSAGE_FILE "m.txt"


int MakeCurTimeStr(char* szCurTimeStr)
{
        struct tm *newtime;
        char am_pm[] = "AM";
        __time64_t long_time;


        _time64( &long_time );           // Get time as 64-bit integer.
                                         // Convert to local time.
        newtime = _localtime64( &long_time ); // C4996
        // Note: _localtime64 deprecated; consider _localetime64_s


        if( newtime->tm_hour > 12 )        // Set up extension.
                strcpy_s( am_pm, sizeof(am_pm), "PM" );
        if( newtime->tm_hour > 12 )        // Convert from 24-hour
                newtime->tm_hour -= 12;    //   to 12-hour clock.
        if( newtime->tm_hour == 0 )        // Set hour to 12 if midnight.
                newtime->tm_hour = 12;


        char buff[30];
memset(buff,0,30);
        asctime_s( buff, sizeof(buff), newtime );
        sprintf( szCurTimeStr,"%.19s %s", buff, am_pm );


   return 0;
}


int main(int argc, char* argv[])
{
SOCKET so_serv,so_client;
struct sockaddr_in serv_addr,client_addr;
int len_client;
int ret;
char* szBuf;
char szTimeStr[40];
FILE* pf;
//FILE* pSpeedFile;
char* szIp;
int iRet,i;
unsigned short nServPort;


WSADATA wsaData;


iRet = WSAStartup(MAKEWORD(2,2), &wsaData);
if(iRet != NO_ERROR)
{
        printf("WSAStartup failed with error: %d\n", iRet);
        return 1;
}
so_serv = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
memset(&serv_addr,0,sizeof(struct sockaddr_in));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
nServPort = (argc > 1) ? atoi(argv[1]) : SERV_PORT;// 是否自行指定端口,若不指定用默认的49999
serv_addr.sin_port = htons(nServPort);


iRet = bind(so_serv,(sockaddr*)&serv_addr,sizeof(struct sockaddr_in));
if(SOCKET_ERROR == iRet)
{
closesocket(so_serv);
WSACleanup();
return -1;
}
iRet = listen(so_serv,SOMAXCONN);
if(SOCKET_ERROR  == iRet)
{
closesocket(so_serv);
WSACleanup();
return -1;
}
printf("Receive server start! Port:%d\n",nServPort);
for(;;)
{
len_client = sizeof(struct sockaddr_in);
memset(&client_addr,0,len_client);
so_client = accept(so_serv,(sockaddr*)&client_addr,&len_client);

   szBuf = (char*)malloc(MAX_BUF_ONE);
memset(szBuf,0,MAX_BUF_ONE);
ret = recv(so_client,(char*)szBuf,(MAX_BUF_ONE-1),0);
if(SOCKET_ERROR != ret && ret > 0)
{
szIp = (char*)malloc(MIN_IP_SIZE);
memset(szIp,0,MIN_IP_SIZE);
strcpy(szIp,inet_ntoa(client_addr.sin_addr));
printf("from:%s : %d, receive:%d Bytes\n",szIp,client_addr.sin_port,ret);
for(i = 0; i < ret; i++)
{
   printf("%02x ",(unsigned char)szBuf[i]);
}
printf("\n");
// 获取当前时间
memset(szTimeStr,0,40);
MakeCurTimeStr(szTimeStr);
// 记录传输内容
pf = fopen(MESSAGE_FILE,"a+");
fprintf(pf,"\n%s\n",szTimeStr);
fprintf(pf,"from:%s : %d, receive:%d Bytes\n",szIp,client_addr.sin_port,ret);
fwrite(szBuf,1,ret,pf);
fprintf(pf,"\n");
fclose(pf);
pf = NULL;
if(szIp != NULL)
{
free(szIp);
szIp = NULL;
}
if(szBuf != NULL)
{
free(szBuf);
szBuf = NULL;
}


}
closesocket(so_client);
}
WSACleanup();


return 0;
}

你可能感兴趣的:(超小型循环式服务器-原生socket编程)