java调用c程序通信示例代码

代码如下:

//===============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 2009年7月15日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转换为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);
}
//Ascii转换为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主机序转换为网络序
void unih2n(LPWSTR uniStr)
{
    for(; *uniStr != 0; uniStr++){
        *uniStr = htons((short)*uniStr);
    }
}
//Unicode网络序转换为主机序
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]);
}

//构建数据函数 retCmdId根据Header中的OP来的。把数据构建到buffer(包含头信息和数据信息)中
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;
}

//构建数据函数 retCmdId根据Header中的OP来的。把现有数据构建到buffer(包含头信息和数据信息)中
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;
  //将buffSource转换为Log结构
  Log * pTmpLog = (Log *)(buffSource);
  //========================================
  pLog->timeLen = htonl(pTmpLog->timeLen);
  pLog->userNameLen = htonl(pTmpLog->userNameLen);
  //========================================
  dataLen = LOG_INFO_TIME_OFFSET;
  //找到buffSource对应time的OFFSET。
  tmpUniStr = (LPWSTR)(buffSource + LOG_INFO_TIME_OFFSET);
  uniChar = tmpUniStr[pTmpLog->timeLen];
  tmpUniStr[pTmpLog->timeLen] = 0;
  //将tmpUniStr里的值转换成本地
  unin2h(tmpUniStr);
  //将Unicode转换为Ascii。并赋值给tmp数组
  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;
  //将tmpUniStr里的值转换成本地
  unin2h(tmpUniStr);
  //将Unicode转换为Ascii。并赋值给tmp数组
  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;
  //找到buffSource对应userName的OFFSET。
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_USERNAME_OFFSET);
  uniChar = tmpUniStr[pTmpSendMsg->userNameLen];
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //将tmpUniStr里的值转换成本地
  unin2h(tmpUniStr);
  //将Unicode转换为Ascii。并赋值给tmp数组
  uni2str(tmpUniStr,tmp);
  tmpUniStr[pTmpSendMsg->userNameLen] = uniChar;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_USERNAME_OFFSET);
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->userNameLen * 2;
  //找到buffSource对应sendMsg的OFFSET。
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_SENDMSG_OFFSET(pTmpSendMsg));
  uniChar = tmpUniStr[pTmpSendMsg->userNameLen];
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //将tmpUniStr里的值转换成本地
  unin2h(tmpUniStr);
  //将Unicode转换为Ascii。并赋值给tmp数组
  uni2str(tmpUniStr,tmp);
  tmpUniStr[pTmpSendMsg->userNameLen] = uniChar;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg));
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->sendMsgLen * 2;
  //找到buffSource对应time的OFFSET。
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_TIME_OFFSET(pTmpSendMsg));
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //将tmpUniStr里的值转换成本地
  unin2h(tmpUniStr);
  //将Unicode转换为Ascii。并赋值给tmp数组
  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;
}
//转换所接收数据,并打印输出,不包含头信息
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("错误:数据解析越界,时间长度无效(%d)/n", pLog->timeLen);
   return;
  }
  //time
  uniStr = (LPWSTR)(buff + LOG_INFO_TIME_OFFSET);
  //这里是把uniStr所切取的字符串最后一位字符给uniChar(因为该位上可能是下一个数据的值)。
  //再让uniStr最后一位为0,成为一个字符串。最后将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("错误:数据解析越界,姓名长度无效(%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("错误:数据解析越界,姓名长度无效(%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("错误:数据解析越界,信息长度无效(%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("错误:数据解析越界,时间长度无效(%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() {
 // 检查 Winsock 版本号,WSAData为WSADATA结构对象
 WSADATA wsaData;
 int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
 if (iResult != NO_ERROR)
  printf("Error at WSAStartup()/n");
 //创建套接字
 SOCKET ConnectSocket;
 ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if (ConnectSocket == INVALID_SOCKET) {
  printf("Error at socket(): %ld/n", WSAGetLastError());
  WSACleanup();
  return;
 }
 //填写远程地址信息
 sockaddr_in clientService;
 clientService.sin_family = AF_INET;
 clientService.sin_port = htons( 27015 );
 //填写服务器程序所在的机器的IP地址
    clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    //连接服务器端
 if ( connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR)
 {
  printf( "Failed to connect./n" );
  WSACleanup();
  return;
 }
    //创建句柄
 HANDLE hCliThread;
 unsigned threadID;
    //产生线程 3.线程创建后调用的函数,4.该函数的参数,6.线程ID 方便对线程进行管理
 hCliThread = (HANDLE)_beginthreadex(NULL,0,SendThread,(void *)ConnectSocket,0,&threadID);
 int bytesRecv = 0;
    //创建一个接收的结构体,用于接收并解析
 Header *recvHeader = (Header *)malloc(HEADER_LEN);
 char* buffer;
 buffer = (char *)malloc(BUFFER_MAX_SIZE);
 for(;;)//recevice data from server
 {
        //接收连接上来的服务端,在客户器端创建一个socket为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;
   }
   //打印数据信息
   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");
 //==================登录 并发送登录信息=================
 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);
 //==================登录 并发送登录信息 结束=================
 //循环发送数据信息给server端
 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);
 }
    //结束线程
 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;//接受的socket
//Unicode转换为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);
}
//AscII转换为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主机序转换为网络序
void unih2n(LPWSTR uniStr)
{
 for(; *uniStr != 0;uniStr++)
 {
  *uniStr = htons((short)*uniStr);
 }
}
//Unicode网络序转换为主机序
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]);
 }
}
//构建数据函数 retCmdId根据Header中的OP来的。把数据构建到buffer(包含头信息和数据信息)中
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;
}

//构建数据函数 retCmdId根据Header中的OP来的。把现有数据构建到buffer(包含头信息和数据信息)中
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;
  //将buffSource转换为Log结构
  Log * pTmpLog = (Log *)(buffSource);
  //========================================
  pLog->timeLen = htonl(pTmpLog->timeLen);
  pLog->userNameLen = htonl(pTmpLog->userNameLen);
  //========================================
  dataLen = LOG_INFO_TIME_OFFSET;
  //找到buffSource对应time的OFFSET。
  tmpUniStr = (LPWSTR)(buffSource + LOG_INFO_TIME_OFFSET);
  uniChar = tmpUniStr[pTmpLog->timeLen];
  tmpUniStr[pTmpLog->timeLen] = 0;
  //将tmpUniStr里的值转换成本地
  //*****************unin2h(tmpUniStr);
  //将Unicode转换为Ascii。并赋值给tmp数组
  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;
  //将tmpUniStr里的值转换成本地
  unin2h(tmpUniStr);
  //将Unicode转换为Ascii。并赋值给tmp数组
  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;
  //找到buffSource对应userName的OFFSET。
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_USERNAME_OFFSET);
  uniChar = tmpUniStr[pTmpSendMsg->userNameLen];
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //将tmpUniStr里的值转换成本地
  unin2h(tmpUniStr);
  //将Unicode转换为Ascii。并赋值给tmp数组
  uni2str(tmpUniStr,tmp);
  tmpUniStr[pTmpSendMsg->userNameLen] = uniChar;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_USERNAME_OFFSET);
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->userNameLen * 2;
  //找到buffSource对应sendMsg的OFFSET。
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_SENDMSG_OFFSET(pTmpSendMsg));
  uniChar = tmpUniStr[pTmpSendMsg->userNameLen];
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //将tmpUniStr里的值转换成本地
  unin2h(tmpUniStr);
  //将Unicode转换为Ascii。并赋值给tmp数组
  uni2str(tmpUniStr,tmp);
  tmpUniStr[pTmpSendMsg->userNameLen] = uniChar;
  uniStr = (LPWSTR)(tmpBuf + SENDMSG_INFO_SENDMSG_OFFSET(pSendMsg));
  str2uni(tmp,uniStr);
  unih2n(uniStr);
  dataLen += pSendMsg->sendMsgLen * 2;
  //找到buffSource对应time的OFFSET。
  tmpUniStr = (LPWSTR)(buffSource + SENDMSG_INFO_TIME_OFFSET(pTmpSendMsg));
  tmpUniStr[pTmpSendMsg->userNameLen] = 0;
  //将tmpUniStr里的值转换成本地
  unin2h(tmpUniStr);
  //将Unicode转换为Ascii。并赋值给tmp数组
  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;
}
//转换所接收数据,并打印输出,不包含头信息
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("错误:数据解析越界,时间长度无效(%d)/n", pLog->timeLen);
   return;
  }
  //time
  uniStr = (LPWSTR)(buff + LOG_INFO_TIME_OFFSET);
  //这里是把uniStr所切取的字符串最后一位字符给uniChar(因为该位上可能是下一个数据的值)。
  //再让uniStr最后一位为0,成为一个字符串。最后将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("错误:数据解析越界,姓名长度无效(%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("错误:数据解析越界,姓名长度无效(%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("错误:数据解析越界,信息长度无效(%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("错误:数据解析越界,时间长度无效(%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));
    // 检查 Winsock 版本号,WSAData为WSADATA结构对象
 WSADATA wsaData;
 int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
 if (iResult != NO_ERROR)
 {
  printf("Error at WSAStartup()/n");
  return;
 }
 //创建套接字
 SOCKET ListenSocket;
 ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if (ListenSocket == INVALID_SOCKET) {
  printf("Error at socket(): %ld/n", WSAGetLastError());
  WSACleanup();
  return;
 }
 //填充sockaddr_in结构
 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);
 //绑定这个套接字到一个本地地址
 if (bind( ListenSocket,(SOCKADDR*)&service,sizeof(service)) == SOCKET_ERROR)
 {
  printf("bind() failed./n");
  closesocket(ListenSocket);
  WSACleanup();
  return;
 }
 // 进入监听模式
 if (listen( ListenSocket, BACKLOG ) == SOCKET_ERROR)
 {
  printf("Error listening on socket./n");
        closesocket(ListenSocket);
  WSACleanup();
  return ;
 }
 printf("listening...../n");
 while(true)
 {
        //循环接收连接上来的客户端
  sClient = accept(ListenSocket,(SOCKADDR*)&remoteAddr,&nAddrLen);
  if(sClient == INVALID_SOCKET)
  {
   printf("Failed accept!/n");
   continue;
  }
  //else
  //{
  // int bytesRecv = 0;
  // //创建一个接收的结构体,用于接收并解析
  // 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;
  //  }
  //  //打印数据信息
  //  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;
  }     
        //创建线程
  HANDLE hThread;
  socketArr[socketLen] = sClient;
  hThread = (HANDLE)_beginthreadex(NULL,0,SockThread,(void *)sClient,0,NULL);
        //用于存储socket的数组下标++
  socketLen++;
 }
    closesocket(ListenSocket);
 WSACleanup();
 return;
 }

//接发数据
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);
 //==================获得连接上来的客户端信息===================
 //暂存接收的数据
 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;
  }
  //将网络序转换为本地序
  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===================
   //buffer中仅有dataInfo没有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;
}

(0)

相关推荐

  • Java Web项目中使用Socket通信多线程、长连接的方法

    很多时候在javaweb项目中我们需要用到Socket通信来实现功能,在web中使用Socket我们需要建立一个监听程序,在程序启动时,启动socket监听.我们的应用场景是在java项目中,需要外接如一个硬件设备,通过tcp通信,获取设备传上来的数据,并对数据做回应. 先看一下web的监听代码: import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class

  • 深入理解JAVA多线程之线程间的通信方式

    一,介绍 本总结我对于JAVA多线程中线程之间的通信方式的理解,主要以代码结合文字的方式来讨论线程间的通信,故摘抄了书中的一些示例代码. 二,线程间的通信方式 ①同步 这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信. 参考示例: public class MyObject { synchronized public void methodA() { //do something.... } synchronized public void methodB()

  • Java Socket通信(一)之客户端程序 发送和接收数据

    网络应用分为客户端和服务端两部分,而Socket类是负责处理客户端通信的Java类.通过这个类可以连接到指定IP或域名的服务器上,并且可以和服务器互相发送和接受数据. 对于Socket通信简述,服务端往Socket的输出流里面写东西,客户端就可以通过Socket的输入流读取对应的内容.Socket与Socket之间是双向连通的,所以客户端也可以往对应的Socket输出流里面写东西,然后服务端对应的Socket的输入流就可以读出对应的内容. 例1:客户端的简略写法(一). Socket clien

  • PHP与Java进行通信的实现方法

    缘起: 最近做了一个电商平台与网银整合的小东西,程序是开源的 Ecmall的,网银的接口也很规范,给出的文档很全,唯一的小问题是,网银使用的签名和验签的lib是只有java和c的,对java还熟悉一些,所以选择了使用java作为签名和验签的接口. 方法: 网上关于php与java交互的资料其实挺多的.总体来说其实也是这么几种方法: •PHP直接通过exec或者system之类的命令调用命令行,然后以java Hello 这种类型得方式来运行java程序,但是缺点是很明显的,不能很好地与java类

  • 使用JAVA实现http通信详解

    Http通信概述 Http通信主要有两种方式POST方式和GET方式.前者通过Http消息实体发送数据给服务器,安全性高,数据传输大小没有限制,后者通过URL的查询字符串传递给服务器参数,以明文显示在浏览器地址栏,保密性差,最多传输2048个字符.但是GET请求并不是一无是处--GET请求大多用于查询(读取资源),效率高.POST请求用于注册.登录等安全性较高且向数据库中写入数据的操作. 除了POST和GET,http通信还有其他方式!请参见http请求的方法 编码前的准备 在进行编码之前,我们

  • 基于Java编写串口通信工具

    最近一门课要求编写一个上位机串口通信工具,我基于Java编写了一个带有图形界面的简单串口通信工具,下面详述一下过程,供大家参考 ^_^ 一: 首先,你需要下载一个额外的支持Java串口通信操作的jar包,由于java.comm比较老了,而且不支持64位系统,这里推荐Rxtx这个jar包(32位/64位均支持). 官方下载地址:http://fizzed.com/oss/rxtx-for-java (注:可能需要FQ才能下载) 不能FQ的童鞋,可以在这里下载: http://xiazai.jb51

  • Java实现的基于socket通信的实例代码

    服务器端代码: 复制代码 代码如下: import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class Server {     public static void main(String[] args) {         ServerSocket server;         try{    

  • Java线程间的通信方式详解

    本总结我对于JAVA多线程中线程之间的通信方式的理解,主要以代码结合文字的方式来讨论线程间的通信,故摘抄了书中的一些示例代码,具体内容如下 ①同步 这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信. 参考示例: public class MyObject { synchronized public void methodA() { //do something.... } synchronized public void methodB() { //do so

  • 基于java TCP网络通信的实例详解

    JAVA中设计网络编程模式的主要有TCP和UDP两种,TCP是属于即时通信,UDP是通过数据包来进行通信,UDP当中就会牵扯到数据的解析和传送.在安全性能方面,TCP要略胜一筹,通信过程中不容易出现数据丢失的现象,有一方中断,两方的通信就会结束,UDP数据包传送的过程当中,一方中断,数据包有很大的可能丢失,还有可能传来的数据包的顺序是错乱的:在效率方面,UDP要比TCP快的不只是一点点的问题,若终端有解析数据方法的函数,数据包就会源源不断的传送过来,然后反馈回去.以上都是我自己的理解,下面是关于

  • php与java通过socket通信的实现代码

    demo实现的简单功能是,接受PHP端写入的字符串,然后原样返回给输出端.代码如下: 复制代码 代码如下: import java.io.*; import java.net.*; public class Server { public static void main(String[] args) throws IOException{   System.out.println("Server started !\n");   ServerSocket server=new Ser

随机推荐