Java calls the c program communication sample code

  • 2020-04-01 02:37:11
  • OfStack


//===============Client Struct================
#pragma pack(push,4)
#define LOG_SEND 0
#define MSG_SEND 1
#define EXIT_SEND 2
#define BUFFER_MAX_SIZE 512
#define HEADER_LEN  sizeof(Header)
typedef struct HeaderStruct
{
 int OP;//OP : 0--> Login  1--> SendMsg  2--> Exit
 int size;
}Header;
//#define LOG_INFO_TIME_OFFSET   (sizeof(Log) - 2 * sizeof(char *))
#define LOG_INFO_TIME_OFFSET  (sizeof(Log) - 2 * sizeof(int))//Modify July 15, 2009 15:15:14
#define LOG_INFO_USERNAME_OFFSET(pLog)   (LOG_INFO_TIME_OFFSET + pLog->timeLen* 2 )
typedef struct LogStruct
{
 int timeLen;
 int userNameLen;
 char* time;
 char* userName; 
}Log;
//#define SENDMSG_INFO_USERNAME_OFFSET   (sizeof(SendMsg) - 3 * sizeof(char *))
#define SENDMSG_INFO_USERNAME_OFFSET  (sizeof(SendMsg) - 3 * sizeof(int))
#define SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg)   (SENDMSG_INFO_USERNAME_OFFSET + pSendMsg->userNameLen * 2)
#define SENDMSG_INFO_TIME_OFFSET(pSendMsg)   (SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg) + pSendMsg->sendMsgLen * 2)
typedef struct SendMsgStruct
{
 int userNameLen;
 int sendMsgLen;
 int timeLen;
 char* userName;
 char* sendMsg;
 char* time;
}SendMsg;
#pragma pack(pop)


#include <stdio.h>
#include <iostream>
#include <process.h>
#include <time.h>
#include <string.h>
#include "winsock2.h"
#include "SendStruct.h"
unsigned __stdcall SendThread(void* socket);
//Unicode to Ascii
void uni2str(const LPWSTR wstr, char *str)
{
 int  len;

 len = wcslen(wstr);
 if(len == 0 ){
  str[0] = 0;
  return;
 }
 memset(str,0,(len+1)*2);
 WideCharToMultiByte(CP_ACP,0,(LPWSTR)wstr,len,str,(len*2 + 1),NULL, NULL);
}
//Convert Ascii to Unicode
void str2uni(const char *str, LPWSTR wstr)
{
 int  len;
 len = strlen(str);
 if(len == 0 ){
  wstr[0] = 0;
  return ; 
 }
 memset((char*)wstr,0,(len+1)*2);
 MultiByteToWideChar(CP_ACP,0,str,len, wstr,(len+1) * 2);
}
//Unicode host order converts to network order
void unih2n(LPWSTR uniStr)
{
    for(; *uniStr != 0; uniStr++){
        *uniStr = htons((short)*uniStr);
    }
}
//Unicode network order to host order
void unin2h(LPWSTR uniStr)
{
 int          i;
 int    len ;
 len = wcslen((wchar_t*)uniStr);
    for(i=0;i<len;i++)
        uniStr[i] = ntohs((short)uniStr[i]);
}
//Build the data function retCmdId based on the OP in the Header. The data is built into a buffer(containing header and data information)
int constructDataBuff(int retCmdId,char *buff)
{
 Header*      pCmdHeader;
 Log*            pLog;
 SendMsg*   pSendMsg;
 int                dataLen = 0;
 char*      tmpBuf;
 LPWSTR    uniStr;
 pCmdHeader = (Header *)buff;
 pCmdHeader->OP = htonl(retCmdId);
 pCmdHeader->size = htonl(pCmdHeader->size);
 tmpBuf = buff + HEADER_LEN;
 if(retCmdId == LOG_SEND)//Send Log Info
 {
  pLog = (Log *)tmpBuf;
  //========================================
  pLog->timeLen = htonl(pLog->timeLen);
  pLog->userNameLen = htonl(pLog->userNameLen);
  //========================================
  uniStr = (LPWSTR)(tmpBuf + LOG_INFO_TIME_OFFSET);
  str2uni(pLog->time,uniStr);
  unih2n(uniStr);
  dataLen += pLog->timeLen ;
  uniStr = (LPWSTR)(tmpBuf + LOG_INFO_USERNAME_OFFSET(pLog));
  str2uni(pLog->userName,uniStr);
  unih2n(uniStr);
  dataLen += pLog->userNameLen;
 }
 else if(retCmdId == MSG_SEND)//Send Msg Info
 {
  pSendMsg = (SendMsg *)tmpBuf;
  //========================================
  pSendMsg->userNameLen = htonl(pSendMsg->userNameLen);
  pSendMsg->sendMsgLen = htonl(pSendMsg->sendMsgLen);
  pSendMsg->timeLen = htonl(pSendMsg->timeLen);
  //========================================
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_USERNAME_OFFSET);
  str2uni(pSendMsg->userName,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->userNameLen * 2;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg));
  str2uni(pSendMsg->sendMsg,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->sendMsgLen * 2;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_TIME_OFFSET(pSendMsg));
  str2uni(pSendMsg->time,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->timeLen * 2;
 }
 pCmdHeader->size = htonl(dataLen);
 dataLen += HEADER_LEN;
 return dataLen;
}
//Build the data function retCmdId based on the OP in the Header. The existing data is built into the buffer(containing header and data information)
int constructDataBuffBySource(int retCmdId,char *buff,char *buffSource)
{
 Header*      pCmdHeader;
 Log*            pLog;
 SendMsg*   pSendMsg;
 int                dataLen = 0;
 char*      tmpBuf;
 LPWSTR    uniStr;
 char             tmp[512];
 LPWSTR     tmpUniStr;
 wchar_t       uniChar;
 pCmdHeader = (Header *)buff;
 pCmdHeader->OP = htonl(retCmdId);
 tmpBuf = buff + HEADER_LEN;
 if(retCmdId == LOG_SEND)//Send Log Info
 {
  pLog = (Log *)tmpBuf;
  //Converts buffSource to a Log structure
  Log * pTmpLog = (Log *)(buffSource);
  //========================================
  pLog->timeLen = htonl(pTmpLog->timeLen);
  pLog->userNameLen = htonl(pTmpLog->userNameLen);
  //========================================
  dataLen = LOG_INFO_TIME_OFFSET;
  //Find the OFFSET of buffSource corresponding to time.
  tmpUniStr = (LPWSTR)(buffSource + LOG_INFO_TIME_OFFSET);
  uniChar = tmpUniStr[pTmpLog->timeLen];
  tmpUniStr[pTmpLog->timeLen] = 0;
  //Converts the values in tmpUniStr to the local value
  unin2h(tmpUniStr);
  // will Unicode to Ascii . And assigned to it tmp An array of 
  uni2str(tmpUniStr,tmp);
  tmpUniStr[pTmpLog->timeLen] = uniChar;
  uniStr = (LPWSTR)(tmpBuf + LOG_INFO_TIME_OFFSET);
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pLog->timeLen  * 2;
  tmpUniStr = (LPWSTR)(buffSource + LOG_INFO_USERNAME_OFFSET(pTmpLog) );
  tmpUniStr[pTmpLog->userNameLen] = 0;
  //Converts the values in tmpUniStr to the local value
  unin2h(tmpUniStr);
  // will Unicode to Ascii . And assigned to it tmp An array of 
  uni2str(tmpUniStr,tmp);
  uniStr = (LPWSTR)(tmpBuf + LOG_INFO_USERNAME_OFFSET(pLog));
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pLog->userNameLen * 2;
 }
 else if(retCmdId == MSG_SEND)//Send Msg Info
 {
  pSendMsg = (SendMsg *)tmpBuf;
  SendMsg * pTmpSendMsg = (SendMsg *)(buffSource);
  //========================================
  pSendMsg->userNameLen = htonl(pTmpSendMsg->userNameLen);
  pSendMsg->sendMsgLen = htonl(pTmpSendMsg->sendMsgLen);
  pSendMsg->timeLen = htonl(pTmpSendMsg->timeLen);
  //========================================

  dataLen = SENDMSG_INFO_USERNAME_OFFSET;
  //Find the buffSource OFFSET for the userName.
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_USERNAME_OFFSET);
  uniChar = tmpUniStr[pTmpSendMsg->userNameLen];
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //Converts the values in tmpUniStr to the local value
  unin2h(tmpUniStr);
  // will Unicode to Ascii . And assigned to it tmp An array of 
  uni2str(tmpUniStr,tmp);
  tmpUniStr[pTmpSendMsg->userNameLen] = uniChar;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_USERNAME_OFFSET);
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->userNameLen * 2;
  //Find the buffSource OFFSET of sendMsg.
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_SENDMSG_OFFSET(pTmpSendMsg));
  uniChar = tmpUniStr[pTmpSendMsg->userNameLen];
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //Converts the values in tmpUniStr to the local value
  unin2h(tmpUniStr);
  // will Unicode to Ascii . And assigned to it tmp An array of 
  uni2str(tmpUniStr,tmp);
  tmpUniStr[pTmpSendMsg->userNameLen] = uniChar;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg));
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->sendMsgLen * 2;
  //Find the OFFSET of buffSource corresponding to time.
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_TIME_OFFSET(pTmpSendMsg));
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //Converts the values in tmpUniStr to the local value
  unin2h(tmpUniStr);
  // will Unicode to Ascii . And assigned to it tmp An array of 
  uni2str(tmpUniStr,tmp);
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_TIME_OFFSET(pSendMsg));
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->timeLen * 2;
 }
 pCmdHeader->size = htonl(dataLen);
 dataLen += HEADER_LEN;
 return dataLen;
}
int constructDataBuffByLog(char *buff, Log * logBuffSource)
{
 Header*      pCmdHeader;
 Log*            pLog;
 int                dataLen = 0;
 char*      tmpBuf;
 LPWSTR    uniStr;
 //int tmpLenTime,tmpLenName;
 pCmdHeader = (Header *)buff;
 pCmdHeader->OP = htonl(0);
 tmpBuf = buff + HEADER_LEN;

 pLog = (Log *)tmpBuf;
 pLog->timeLen = logBuffSource->timeLen;
 pLog->userNameLen = logBuffSource->userNameLen;
 dataLen = LOG_INFO_TIME_OFFSET;
 uniStr = (LPWSTR)(tmpBuf + LOG_INFO_TIME_OFFSET);
 str2uni(logBuffSource->time,uniStr);
 unih2n(uniStr);
 dataLen += pLog->timeLen  * 2;
 int len = LOG_INFO_USERNAME_OFFSET(pLog);
 uniStr = (LPWSTR)(tmpBuf + LOG_INFO_USERNAME_OFFSET(pLog));
 str2uni(logBuffSource->userName,uniStr);
 unih2n(uniStr);
 dataLen += pLog->userNameLen * 2;

 pLog->timeLen = htonl(pLog->timeLen);
 pLog->userNameLen = htonl(pLog->userNameLen);

 pCmdHeader->size = htonl(dataLen);
 dataLen += HEADER_LEN;
 return dataLen;
}
int constructDataBuffBySendMsg(char *buff,SendMsg * sendMsgSource)
{
 Header*      pCmdHeader;
 SendMsg*   pSendMsg;
 int                dataLen = 0;
 char*      tmpBuf;
 LPWSTR    uniStr;
 pCmdHeader = (Header *)buff;
 pCmdHeader->OP = htonl(1);
 tmpBuf = buff + HEADER_LEN;
 pSendMsg = (SendMsg *)tmpBuf;
 pSendMsg->userNameLen = sendMsgSource->userNameLen;
 pSendMsg->sendMsgLen = sendMsgSource->sendMsgLen;
 pSendMsg->timeLen = sendMsgSource->timeLen;
 dataLen = SENDMSG_INFO_USERNAME_OFFSET;
 uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_USERNAME_OFFSET);
 printf("in constructDataBuffBySendMsg  --- the sendMsgSource->userName is %s/n",sendMsgSource->userName);
 str2uni(sendMsgSource->userName, uniStr);
 unih2n(uniStr);
 dataLen += pSendMsg->userNameLen * 2;
 uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg));
 //=======error=======
 int len = SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg);
 printf("%s",sendMsgSource->sendMsg);
 str2uni(sendMsgSource->sendMsg,uniStr);
 unih2n(uniStr);
 dataLen += pSendMsg->sendMsgLen * 2;
 uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_TIME_OFFSET(pSendMsg));
 str2uni(sendMsgSource->time,uniStr);
 unih2n(uniStr);
 dataLen += pSendMsg->timeLen * 2;
 pSendMsg->userNameLen = htonl(pSendMsg->userNameLen);
 pSendMsg->sendMsgLen = htonl(pSendMsg->sendMsgLen);
 pSendMsg->timeLen = htonl(pSendMsg->timeLen);
 pCmdHeader->size = htonl(dataLen);
 dataLen += HEADER_LEN;
 return dataLen;
}
//Converts the received data and prints the output without header information
void convertDataAndPrint(int cmdId,char *buff, unsigned int dataLen)
{
 Log *pLog;
 SendMsg *pSendMsg;
 char tmp[512];
 //char * tmpBuf;
 LPWSTR uniStr;
 wchar_t uniChar;
 //int i;
 unsigned int len;

 printf("/n=====================================================/n");
 if(cmdId == LOG_SEND)
 {
  pLog = (Log *)(buff);
  pLog->timeLen = ntohl(pLog->timeLen);
  pLog->userNameLen = ntohl(pLog->userNameLen);
  len =LOG_INFO_TIME_OFFSET + pLog->timeLen * 2;
  if(len > dataLen)
  {
   printf(" Error: data parsing out of bounds, time length invalid (%d)/n", pLog->timeLen);
   return;
  }
  //time
  uniStr = (LPWSTR)(buff + LOG_INFO_TIME_OFFSET);
  //Here, the last character of the string cut by uniStr is given to uniChar(because that bit may be the value of the next data).
  //I'm going to make the last bit of uniStr zero, which is a string. Finally, return the values in uniChar
  uniChar = uniStr[pLog->timeLen];
  //the end is '/0'
  uniStr[pLog->timeLen] = 0;
  //Unicode network order Trans To Host order
  unin2h(uniStr);
  //Unicode Trans To AscII,tmp is char(single char)
  uni2str(uniStr,tmp);
  uniStr[pLog->timeLen] = uniChar;
  printf("[%s]:  ",tmp);  
  len += pLog->userNameLen * 2;
  if(len > dataLen)
  {
   printf(" Error: data parsing out of bounds, name length invalid (%d)/n", pLog->userNameLen);
   return;
  }
  //userName
  uniStr = (LPWSTR)(buff + LOG_INFO_USERNAME_OFFSET(pLog));
  //uniChar = uniStr[pLog->userNameLen];
  uniStr[pLog->userNameLen] = 0;
  unin2h(uniStr);
  uni2str(uniStr,tmp);
  //uniStr[pLog->userNameLen] = uniChar;
  printf("%s  connected.../n",tmp);  
  printf("=====================LogInfo End=======================/n");
 }
 else if(cmdId == MSG_SEND)
 {
  pSendMsg = (SendMsg *)buff;
  pSendMsg->userNameLen = ntohl(pSendMsg->userNameLen);
  pSendMsg->sendMsgLen = ntohl(pSendMsg->sendMsgLen);
  pSendMsg->timeLen = ntohl(pSendMsg->timeLen);
  len = SENDMSG_INFO_USERNAME_OFFSET + pSendMsg->userNameLen * 2;
  if(len > dataLen)
  {
   printf(" Error: data parsing out of bounds, name length invalid (%d)/n", pSendMsg->userNameLen);
   return;
  }
  //userName
  uniStr = (LPWSTR)(buff + SENDMSG_INFO_USERNAME_OFFSET);
  uniChar = uniStr[pSendMsg->userNameLen];
  uniStr[pSendMsg->userNameLen] = 0;
  unin2h(uniStr);
  uni2str(uniStr,tmp);
  uniStr[pSendMsg->userNameLen] = uniChar;
  printf("[%s]   ",tmp);
  len += pSendMsg->sendMsgLen * 2;
  if(len > dataLen)
  {
   printf(" Error: data parsing out of bounds, message length invalid (%d)/n",pSendMsg->sendMsgLen);
   return;
  }

  //sendMsg  
  long len2 =SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg);
  len2 = ntohl(len2);
  uniStr = (LPWSTR)(buff + SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg));
  //long len2 =SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg);
  uniChar = uniStr[pSendMsg->sendMsgLen];
  uniStr[pSendMsg->sendMsgLen] = 0;
  unin2h(uniStr);
  uni2str(uniStr,tmp);
  uniStr[pSendMsg->sendMsgLen] = uniChar;
  printf("  %s  ",tmp);
  len += pSendMsg->timeLen * 2;
  if(len > dataLen)
  {
   printf(" Error: data parsing out of bounds, time length invalid (%d)/n",pSendMsg->timeLen);
   return;
  }
  //time
  uniStr = (LPWSTR) (buff + SENDMSG_INFO_TIME_OFFSET(pSendMsg));
  uniStr[pSendMsg->timeLen] = 0;
  unin2h(uniStr);
  uni2str(uniStr,tmp);
  printf(" [%s] /n",tmp);
  printf("====================SendMsgInfo End====================/n");
 }
}
void main() {
 //Check the Winsock version number that WSAData is a WSAData structure object
 WSADATA wsaData;
 int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
 if (iResult != NO_ERROR)
  printf("Error at WSAStartup()/n");
 //Create a socket
 SOCKET ConnectSocket;
 ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if (ConnectSocket == INVALID_SOCKET) {
  printf("Error at socket(): %ld/n", WSAGetLastError());
  WSACleanup();
  return;
 }
 //Fill in the remote address information
 sockaddr_in clientService; 
 clientService.sin_family = AF_INET;
 clientService.sin_port = htons( 27015 );
 //Fill in the IP address of the machine on which the server program resides
    clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    //Connect to server side
 if ( connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) 
 {
  printf( "Failed to connect./n" );
  WSACleanup();
  return;
 }
    //Create a handle
 HANDLE hCliThread;
 unsigned threadID;
    //3. Function called after thread creation, 4. Parameter of this function, 6. Thread ID is convenient for thread management
 hCliThread = (HANDLE)_beginthreadex(NULL,0,SendThread,(void *)ConnectSocket,0,&threadID);
 int bytesRecv = 0;
    //Creates a received structure to receive and parse
 Header *recvHeader = (Header *)malloc(HEADER_LEN);
 char* buffer;
 buffer = (char *)malloc(BUFFER_MAX_SIZE);
 for(;;)//recevice data from server
 {
        //Receive the connected server and create a socket on the client side as a ConnectSocket
  bytesRecv = recv(ConnectSocket,(char *)recvHeader,HEADER_LEN,0);
  if(bytesRecv <= 0 || bytesRecv == WSAECONNRESET)
  {
   printf("client didn't recv data from server,then disconnect with server, %d/n", WSAGetLastError());
   break;
  }

  recvHeader->OP = ntohl(recvHeader->OP);
  recvHeader->size = ntohl(recvHeader->size);
  printf("recv HeaderInfo: OP: %d ,size : %d /n",recvHeader->OP,recvHeader->size);
  if(recvHeader->size > 0 && recvHeader->size < BUFFER_MAX_SIZE)
  {
   bytesRecv = recv(ConnectSocket,buffer,recvHeader->size,0);
   if(bytesRecv <= 0 || bytesRecv == WSAECONNRESET)
   {
    printf("client disconnect with server(%d)",WSAGetLastError());
    break;
   }
   //Print data information
   convertDataAndPrint(recvHeader->OP,buffer,recvHeader->size);
  }
 }
 free(buffer);
 WSACleanup();
 return;
}
unsigned __stdcall SendThread(void *socket)//send data to otherclient and server
{
 Header header;
 SendMsg sendMsg;
 Log log;
 int dataLen;
 char *buffer;
 char pUserName[40];
 char pSendMsg[512];
 //int userNameLen;
 char time[8] = "2009";
 buffer = (char *)malloc(BUFFER_MAX_SIZE);
 printf("======Welcome  to YY ChatRoom======/n");
 printf("========Log========:/n");
 //================== ==== login and send login information =========
 printf("Your Name : ");
 scanf("%s",pUserName);
 printf("your name is: %s/n",pUserName);
 log.userName = pUserName;
 log.userNameLen = strlen(log.userName);
 //_strtime(time);
 log.time = time;
 log.timeLen = strlen(log.time);

 header.OP = 0;
 dataLen = constructDataBuffByLog(buffer,&log);
 int sendLen = send((SOCKET)socket,buffer,dataLen,0);
 printf("the DataLen is : %d  the SendLen is %d/n",dataLen,sendLen);
 if (sendLen < 0)
 {
  printf("Client: disconnect with server,(%d)", WSAGetLastError());
  return 0;
 }
 memset(buffer,0,BUFFER_MAX_SIZE);
 //===========
 //Loop sends data information to the server side
 while(1)
 {
  sendMsg.userName = pUserName;
  sendMsg.userNameLen =strlen(pUserName);
  printf("Input:");
  scanf("%s",pSendMsg);
  sendMsg.sendMsg = pSendMsg;
  sendMsg.sendMsgLen = strlen(sendMsg.sendMsg);
  //_strtime(time);
  sendMsg.time = time;
  sendMsg.timeLen = strlen(sendMsg.time);
  header.OP = htonl(1);
  //header.size = htonl(sendMsg.userNameLen + sendMsg.sendMsgLen + sendMsg.timeLen);
  dataLen = constructDataBuffBySendMsg(buffer,&sendMsg);
  int sendLen = send((SOCKET)socket,buffer,dataLen,0);
  if(sendLen  < 0)
  {
   printf("Client: disconnect with server/n");
      break;
  } 
  printf("the dataLen is (%d),the sendLen is(%d)/n",dataLen,sendLen);
  memset(buffer,0,BUFFER_MAX_SIZE);
 }
    //The end of the thread
 free(buffer);
 _endthreadex( 0 );
 return 0;
}


#define BACKLOG (int)20  
#include <stdio.h>
#include <process.h>
#include "winsock2.h"
#include <time.h>
#include "SendStruct.h"
unsigned __stdcall SockThread(void *socket);
//CRITICALSECTION CriticalSection;//define critical resource
SOCKET socketArr[BACKLOG];//save socket from client
HOSTENT *host;
//struct MsgStruct clientNameStr[BACKLOG];//save recv name from client
static int socketLen = 0;
sockaddr_in remoteAddr;//Accept the socket
//Unicode to AscII
void uni2str(const LPWSTR wstr,char *str)
{
 int len;
 len = wcslen(wstr);
 if(len == 0)
 {
  str[0] = 0;
  return;
 }
 memset(str,0,(len + 1) * 2);
 WideCharToMultiByte(CP_ACP,0,(LPWSTR)wstr,len,str,(len * 2 + 1),NULL,NULL);
}
//Convert AscII to Unicode
void str2uni(const char *str,LPWSTR wstr)
{
 int len;
 len = strlen(str);
 if(len == 0)
 {
  wstr[0] = 0;
  return;
 }
 memset((char *)wstr,0,(len + 1) * 2);
 MultiByteToWideChar(CP_ACP,0,str,len,wstr,(len + 1) * 2);
}
//Unicode host order converts to network order
void unih2n(LPWSTR uniStr)
{
 for(; *uniStr != 0;uniStr++)
 {
  *uniStr = htons((short)*uniStr);
 }
}
//Unicode network order to host order
void unin2h(LPWSTR uniStr)
{
 int i;
 int len;
 len = wcslen((wchar_t*)uniStr);
 for(i = 0;i < len;i++)
 {
  uniStr[i] = ntohs((short)uniStr[i]);
 }
}
//Build the data function retCmdId based on the OP in the Header. The data is built into a buffer(containing header and data information)
int constructDataBuff(int retCmdId,char *buff)
{
 //Header*      pCmdHeader = (Header *)malloc(HEADER_LEN);
 Log*            pLog;
 SendMsg*   pSendMsg;
 int                dataLen = 0;
 char*      tmpBuf;
 LPWSTR    uniStr;
 //pCmdHeader = (Header *)buff;
 //pCmdHeader->OP = htonl(retCmdId);
 //pCmdHeader->size = htonl(pCmdHeader->size);
 //tmpBuf = buff + HEADER_LEN;
 tmpBuf = buff;
 if(retCmdId == LOG_SEND)//Send Log Info
 {
  pLog = (Log *)tmpBuf;
  //========================================

  //========================================
  uniStr = (LPWSTR)(tmpBuf + LOG_INFO_TIME_OFFSET);
  str2uni(pLog->time,uniStr);
  unih2n(uniStr);
  dataLen += pLog->timeLen ;
  uniStr = (LPWSTR)(tmpBuf + LOG_INFO_USERNAME_OFFSET(pLog));
  str2uni(pLog->userName,uniStr);
  unih2n(uniStr);
  dataLen += pLog->userNameLen;
  pLog->timeLen = htonl(pLog->timeLen);
  pLog->userNameLen = htonl(pLog->userNameLen);
 }
 else if(retCmdId == MSG_SEND)//Send Msg Info
 {
  pSendMsg = (SendMsg *)tmpBuf;
  //========================================
  //pSendMsg->userNameLen = pSendMsg->userNameLen;
  //pSendMsg->sendMsgLen =pSendMsg->sendMsgLen;
  //pSendMsg->timeLen = pSendMsg->timeLen;
  //========================================
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_USERNAME_OFFSET);
  str2uni(pSendMsg->userName,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->userNameLen * 2;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg));
  int tmpLen = SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg);
  //tmpLen = pSendMsg->sendMsgLen;
  str2uni(pSendMsg->sendMsg,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->sendMsgLen * 2;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_TIME_OFFSET(pSendMsg));
  tmpLen = SENDMSG_INFO_TIME_OFFSET(pSendMsg);
  tmpLen = pSendMsg->timeLen;
  str2uni(pSendMsg->time,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->timeLen * 2;
  pSendMsg->userNameLen = htonl(pSendMsg->userNameLen);
  pSendMsg->sendMsgLen = htonl(pSendMsg->sendMsgLen);
  pSendMsg->timeLen = htonl(pSendMsg->timeLen);
 }
 //pCmdHeader->size = htonl(dataLen);
 dataLen += HEADER_LEN;
 return dataLen;
}
//Build the data function retCmdId based on the OP in the Header. The existing data is built into the buffer(containing header and data information)
int constructDataBuffBySource(int retCmdId,char *buff,char *buffSource)
{
 Header*      pCmdHeader;
 Log*            pLog;
 SendMsg*   pSendMsg;
 int                dataLen = 0;
 char*      tmpBuf;
 LPWSTR    uniStr;
 char             tmp[512];
 LPWSTR     tmpUniStr;
 wchar_t       uniChar;
 pCmdHeader = (Header *)buff;
 pCmdHeader->OP = htonl(retCmdId);
 tmpBuf = buff + HEADER_LEN;
 if(retCmdId == LOG_SEND)//Send Log Info
 {
  pLog = (Log *)tmpBuf;
  //Converts buffSource to a Log structure
  Log * pTmpLog = (Log *)(buffSource);
  //========================================
  pLog->timeLen = htonl(pTmpLog->timeLen);
  pLog->userNameLen = htonl(pTmpLog->userNameLen);
  //========================================
  dataLen = LOG_INFO_TIME_OFFSET;
  //Find the OFFSET of buffSource corresponding to time.
  tmpUniStr = (LPWSTR)(buffSource + LOG_INFO_TIME_OFFSET);
  uniChar = tmpUniStr[pTmpLog->timeLen];
  tmpUniStr[pTmpLog->timeLen] = 0;
  //Converts the values in tmpUniStr to the local value
  //*****************unin2h(tmpUniStr);
  //Converts Unicode to Ascii. And assign to the TMP array
  uni2str(tmpUniStr,tmp);
  tmpUniStr[pTmpLog->timeLen] = uniChar;
  uniStr = (LPWSTR)(tmpBuf + LOG_INFO_TIME_OFFSET);
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pLog->timeLen  * 2;
  tmpUniStr = (LPWSTR)(buffSource + LOG_INFO_USERNAME_OFFSET(pTmpLog) );
  tmpUniStr[pTmpLog->userNameLen] = 0;
  //Converts the values in tmpUniStr to the local value
  unin2h(tmpUniStr);
  //Converts Unicode to Ascii. And assign to the TMP array
  uni2str(tmpUniStr,tmp);
  uniStr = (LPWSTR)(tmpBuf + LOG_INFO_USERNAME_OFFSET(pLog));
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pLog->userNameLen * 2;
 }
 else if(retCmdId == MSG_SEND)//Send Msg Info
 {
  pSendMsg = (SendMsg *)tmpBuf;
  SendMsg * pTmpSendMsg = (SendMsg *)(buffSource);
  //========================================
  pSendMsg->userNameLen = htonl(pTmpSendMsg->userNameLen);
  pSendMsg->sendMsgLen = htonl(pTmpSendMsg->sendMsgLen);
  pSendMsg->timeLen = htonl(pTmpSendMsg->timeLen);
  //========================================

  dataLen = SENDMSG_INFO_USERNAME_OFFSET;
  //Find the buffSource OFFSET for the userName.
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_USERNAME_OFFSET);
  uniChar = tmpUniStr[pTmpSendMsg->userNameLen];
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //Converts the values in tmpUniStr to the local value
  unin2h(tmpUniStr);
  //Converts Unicode to Ascii. And assign to the TMP array
  uni2str(tmpUniStr,tmp);
  tmpUniStr[pTmpSendMsg->userNameLen] = uniChar;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_USERNAME_OFFSET);
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->userNameLen * 2;
  //Find the buffSource OFFSET of sendMsg.
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_SENDMSG_OFFSET(pTmpSendMsg));
  uniChar = tmpUniStr[pTmpSendMsg->userNameLen];
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //Converts the values in tmpUniStr to the local value
  unin2h(tmpUniStr);
  //Converts Unicode to Ascii. And assign to the TMP array
  uni2str(tmpUniStr,tmp);
  tmpUniStr[pTmpSendMsg->userNameLen] = uniChar;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg));
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->sendMsgLen * 2;
  //Find the OFFSET of buffSource corresponding to time.
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_TIME_OFFSET(pTmpSendMsg));
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //Converts the values in tmpUniStr to the local value
  unin2h(tmpUniStr);
  //Converts Unicode to Ascii. And assign to the TMP array
  uni2str(tmpUniStr,tmp);
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_TIME_OFFSET(pSendMsg));
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->timeLen * 2;
 }
 pCmdHeader->size = htonl(dataLen);
 dataLen += HEADER_LEN;
 return dataLen;
}
int constructDataBuffByLog(char *buff, Log * logBuffSource)
{
 Header*      pCmdHeader;
 Log*            pLog;
 int                dataLen = 0;
 char*      tmpBuf;
 LPWSTR    uniStr;
 pCmdHeader = (Header *)buff;
 pCmdHeader->OP = htonl(0);
 tmpBuf = buff + HEADER_LEN;

 pLog = (Log *)tmpBuf;
 //========================================
 pLog->timeLen = htonl(logBuffSource->timeLen);
 pLog->userNameLen = htonl(logBuffSource->userNameLen);
 //========================================
 dataLen = LOG_INFO_TIME_OFFSET;
 uniStr = (LPWSTR)(tmpBuf + LOG_INFO_TIME_OFFSET);
 str2uni(logBuffSource->time,uniStr);
 unih2n(uniStr);
 dataLen += pLog->timeLen  * 2;
 uniStr = (LPWSTR)(tmpBuf + LOG_INFO_USERNAME_OFFSET(pLog));
 str2uni(logBuffSource->userName,uniStr);
 unih2n(uniStr);
 dataLen += pLog->userNameLen * 2;

 pCmdHeader->size = htonl(dataLen);
 dataLen += HEADER_LEN;
 return dataLen;
}
int constructDataBuffBySendMsg(char *buff,SendMsg * sendMsgSource)
{
 Header*      pCmdHeader;
 SendMsg*   pSendMsg;
 int                dataLen = 0;
 char*      tmpBuf;
 LPWSTR    uniStr;
 pCmdHeader = (Header *)buff;
 pCmdHeader->OP = htonl(1);
 tmpBuf = buff + HEADER_LEN;
 pSendMsg = (SendMsg *)tmpBuf;
 pSendMsg->userNameLen = sendMsgSource->userNameLen;
 pSendMsg->sendMsgLen = sendMsgSource->sendMsgLen;
 pSendMsg->timeLen = sendMsgSource->timeLen;
 dataLen = SENDMSG_INFO_USERNAME_OFFSET;
 uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_USERNAME_OFFSET);
 str2uni(sendMsgSource->userName,uniStr);
 unih2n(uniStr);
 dataLen += pSendMsg->userNameLen * 2;
 uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg));
 //=======error=======
 int len = SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg);
 printf("%s",sendMsgSource->sendMsg);
 str2uni(sendMsgSource->sendMsg,uniStr);
 unih2n(uniStr);
 dataLen += pSendMsg->sendMsgLen * 2;
 uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_TIME_OFFSET(pSendMsg));
 str2uni(sendMsgSource->time,uniStr);
 unih2n(uniStr);
 dataLen += pSendMsg->timeLen * 2;
 pSendMsg->userNameLen = htonl(pSendMsg->userNameLen);
 pSendMsg->sendMsgLen = htonl(pSendMsg->sendMsgLen);
 pSendMsg->timeLen = htonl(pSendMsg->timeLen);
 pCmdHeader->size = htonl(dataLen);
 dataLen += HEADER_LEN;
 return dataLen;
}
//Converts the received data and prints the output without header information
void convertDataAndPrint(int cmdId,char *buff, unsigned int dataLen)
{
 Log *pLog;
 SendMsg *pSendMsg;
 char tmp[512];
 LPWSTR uniStr;
 wchar_t uniChar;
 unsigned int len;

 printf("=====================================================/n");
 if(cmdId == LOG_SEND)
 {
  pLog = (Log *)(buff);
  pLog->timeLen = ntohl(pLog->timeLen);
  pLog->userNameLen = ntohl(pLog->userNameLen);
  len =LOG_INFO_TIME_OFFSET + pLog->timeLen * 2;
  if(len > dataLen)
  {
   printf(" Error: data parsing out of bounds, time length invalid (%d)/n", pLog->timeLen);
   return;
  }
  //time
  uniStr = (LPWSTR)(buff + LOG_INFO_TIME_OFFSET);
  //Here, the last character of the string cut by uniStr is given to uniChar(because that bit may be the value of the next data).
  //I'm going to make the last bit of uniStr zero, which is a string. Finally, return the values in uniChar
  uniChar = uniStr[pLog->timeLen];
  //the end is '/0'
  uniStr[pLog->timeLen] = 0;
  //Unicode network order Trans To Host order
  unin2h(uniStr);
  //Unicode Trans To AscII,tmp is char(single char)
  uni2str(uniStr,tmp);
  uniStr[pLog->timeLen] = uniChar;
  printf("[%s]:  ",tmp);  
  len += pLog->userNameLen * 2;
  if(len > dataLen)
  {
   printf(" Error: data parsing out of bounds, name length invalid (%d)/n", pLog->userNameLen);
   return;
  }
  //userName
  uniStr = (LPWSTR)(buff + LOG_INFO_USERNAME_OFFSET(pLog));
  uniChar = uniStr[pLog->userNameLen];
  uniStr[pLog->userNameLen] = 0;
  unin2h(uniStr);
  uni2str(uniStr,tmp);
  uniStr[pLog->userNameLen] = uniChar;
  printf("%s  connected.../n",tmp);  
  printf("=====================LogInfo End=======================/n");
 }
 else if(cmdId == MSG_SEND)
 {
  pSendMsg = (SendMsg *)buff;
  pSendMsg->userNameLen = ntohl(pSendMsg->userNameLen);
  pSendMsg->sendMsgLen = ntohl(pSendMsg->sendMsgLen);
  pSendMsg->timeLen = ntohl(pSendMsg->timeLen);
  len = SENDMSG_INFO_USERNAME_OFFSET + pSendMsg->userNameLen * 2;
  if(len > dataLen)
  {
   printf(" Error: data parsing out of bounds, name length invalid (%d)/n", pSendMsg->userNameLen);
   return;
  }
  //userName
  uniStr = (LPWSTR)(buff + SENDMSG_INFO_USERNAME_OFFSET);
  uniChar = uniStr[pSendMsg->userNameLen];
  uniStr[pSendMsg->userNameLen] = 0;
  unin2h(uniStr);
  uni2str(uniStr,tmp);
  uniStr[pSendMsg->userNameLen] = uniChar;
  printf("[%s]   ",tmp);
  len += pSendMsg->sendMsgLen * 2;
  if(len > dataLen)
  {
   printf(" Error: data parsing out of bounds, message length invalid (%d)/n",pSendMsg->sendMsgLen);
   return;
  }

  //sendMsg
  uniStr = (LPWSTR)(buff + SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg));
  uniChar = uniStr[pSendMsg->sendMsgLen];
  uniStr[pSendMsg->sendMsgLen] = 0;
  unin2h(uniStr);
  uni2str(uniStr,tmp);
  uniStr[pSendMsg->sendMsgLen] = uniChar;
  printf("  %s  ",tmp);
  len += pSendMsg->timeLen * 2;
  if(len > dataLen)
  {
   printf(" Error: data parsing out of bounds, time length invalid (%d)/n",pSendMsg->timeLen);
   return;
  }
  //time
  uniStr = (LPWSTR) (buff + SENDMSG_INFO_TIME_OFFSET(pSendMsg));
  uniChar = uniStr[pSendMsg->sendMsgLen];
  uniStr[pSendMsg->timeLen] = 0;
  unin2h(uniStr);
  uni2str(uniStr,tmp);
  uniStr[pSendMsg->sendMsgLen] = uniChar;
  printf(" [%s]/n",tmp);
  printf("====================SendMsgInfo End====================/n");
 }
}
void main() 
{
    //INITIALIZECRITICALSECTION CriticalSection;
 int nAddrLen = sizeof(remoteAddr);
 SOCKET sClient;
 memset(&socketArr,0,sizeof(socketLen));
    //Check the Winsock version number that WSAData is a WSAData structure object
 WSADATA wsaData;
 int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
 if (iResult != NO_ERROR)
 {
  printf("Error at WSAStartup()/n");
  return;
 }
 //Create a socket
 SOCKET ListenSocket;
 ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if (ListenSocket == INVALID_SOCKET) {
  printf("Error at socket(): %ld/n", WSAGetLastError());
  WSACleanup();
  return;
 }
 //Fill the sockaddr_in structure
 sockaddr_in service;
 service.sin_family = AF_INET;
 service.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    service.sin_port = htons(27015);
 //Bind the socket to a local address
 if (bind( ListenSocket,(SOCKADDR*)&service,sizeof(service)) == SOCKET_ERROR) 
 {
  printf("bind() failed./n");
  closesocket(ListenSocket);
  WSACleanup();
  return;
 }
 //Go into listening mode
 if (listen( ListenSocket, BACKLOG ) == SOCKET_ERROR)
 {
  printf("Error listening on socket./n");
        closesocket(ListenSocket);
  WSACleanup();
  return ;
 }
 printf("listening...../n");
 while(true)
 {
        //The loop receives the connected client
  sClient = accept(ListenSocket,(SOCKADDR*)&remoteAddr,&nAddrLen);
  if(sClient == INVALID_SOCKET)
  {
   printf("Failed accept!/n");
   continue;
  }
  //else
  //{
  // int bytesRecv = 0;
  // // Creates a received structure to receive and parse 
  // Header *recvHeader = (Header *)malloc(HEADER_LEN);
  // char* buffer;
  // buffer = (char *)malloc(BUFFER_MAX_SIZE);
  // bytesRecv = recv(sClient,(char *)recvHeader,HEADER_LEN,0);
  // if(bytesRecv <= 0 || bytesRecv == WSAECONNRESET)
  // {
  //  printf("server didn't recv data from client,then disconnect with server, %d/n", WSAGetLastError());
  //  break;
  // }
  // 
  // recvHeader->OP = ntohl(recvHeader->OP);
  // recvHeader->size = ntohl(recvHeader->size);
  // printf("recv HeaderInfo: OP: %d ,size : %d /n",recvHeader->OP,recvHeader->size);
  // if(recvHeader->size > 0 && recvHeader->size < BUFFER_MAX_SIZE)
  // {
  //  bytesRecv = recv(sClient,buffer,recvHeader->size,0);
  //  if(bytesRecv <= 0 || bytesRecv == WSAECONNRESET)
  //  {
  //   printf("client disconnect with server(%d)/n",WSAGetLastError());
  //   break;
  //  }
  //  // Print data information 
  //  convertDataAndPrint(recvHeader->OP,buffer,recvHeader->size);
  // }
  //}
  //====================================
  host = gethostbyaddr((char *)&remoteAddr.sin_addr.s_addr,4,AF_INET);
  printf("/nClient ( %s : %s ) connect with server!/n", host->h_name, inet_ntoa(remoteAddr.sin_addr));
  //====================================
  if(socketLen > BACKLOG)
  {
   printf("go beyond the limit 10!/n");
   sClient = NULL;
   break;
  }     
        //Create a thread
  HANDLE hThread;
  socketArr[socketLen] = sClient;
  hThread = (HANDLE)_beginthreadex(NULL,0,SockThread,(void *)sClient,0,NULL);
        //Array subscripts used to store sockets ++
  socketLen++;
 }
    closesocket(ListenSocket);
 WSACleanup();
 return;
 }

//Receiving data
unsigned __stdcall SockThread(void *socket)
{
  int cnInt = socketLen - 1;

  int bytesRecv = SOCKET_ERROR;
  Header *recvHeader = (Header *)malloc(HEADER_LEN);
  char*  buffer;
  //char*  tmpBuf;
  char* clientIP;
  struct sockaddr_in client_message;
  int  client_len = sizeof(struct sockaddr_in);
  int dataLen;
  //=================== ======
 bytesRecv = getsockname((SOCKET)socket,(struct sockaddr *)&client_message,&client_len);
 clientIP = inet_ntoa(client_message.sin_addr);
 //=================== ======
 //Temporary storage of received data
 buffer = (char *)malloc(BUFFER_MAX_SIZE);
 while(1)
 {
  bytesRecv = recv((SOCKET)socket,(char*)recvHeader,HEADER_LEN,0);
  if(bytesRecv <= 0 || bytesRecv == WSAECONNRESET)
  {
   printf("server : Client (%s) connection closed/n",clientIP);
   closesocket(socketArr[cnInt]);
   socketArr[cnInt] = NULL;
   break;
  }
  //Converts the network order to the local order
  recvHeader->OP = ntohl(recvHeader->OP);
  recvHeader->size = ntohl(recvHeader->size);
  printf("/n=======recv command:%d ; dataLen : %d./n",recvHeader->OP,recvHeader->size);

  if(recvHeader->size > 0 && recvHeader->size < BUFFER_MAX_SIZE)
  {
   bytesRecv = recv((SOCKET)socket,buffer,recvHeader->size,0);
   if(bytesRecv <= 0 || bytesRecv == WSAECONNRESET)
   {
    if(bytesRecv == 0)
    {
     printf("server : SendMsg Info recv failed/n");
    }
    else if(bytesRecv < 0)
    {
     printf("server: recv data failed! disconnect with client(%s)/n",clientIP);
    }
    break;
   }
   //===============send to other client begin==================
   if(recvHeader->OP == 0 || recvHeader->OP == 1)
   {
    for(int i = 0 ; i < socketLen; i++)
    {
     if((SOCKET)socket != socketArr[i])
     {
      int dataLen = recvHeader->size;
      recvHeader->OP = htonl(recvHeader->OP);
      recvHeader->size = htonl(recvHeader->size);
      send((SOCKET)socketArr[i],(char *)recvHeader,HEADER_LEN,0);
      if((send((SOCKET)socketArr[i],buffer,dataLen,0)) < 0 )
      {
       printf("server: client(%s) disconnect with server!/n",clientIP);
       break;
      }
     }
    }   
   }
   else
   {
    printf("Send OP error.you must select it which is 0 or 1/n");
   }
            //===============send to other client end===================
   //Only dataInfo is in the buffer without headerInfo
   convertDataAndPrint(recvHeader->OP,buffer,recvHeader->size);
  }
  else
  {
   if(recvHeader->size > 0)
   {
    printf("The client (%s) send the dataLen(%d) larger buffer size(%d).please input small again!/n",
     clientIP,recvHeader->size,BUFFER_MAX_SIZE);
   }
   else
   {
    printf("The client (%s) send the dataLen(%d) less than 0./ndisconnection with server/n",
     clientIP,recvHeader->size);
    //break;
   }
  }
  //memset(buffer,0,recvHeader->size);
 }
  free(buffer);
 _endthreadex( 0 );
 return 0;
}


Related articles: