当前位置: 移动技术网 > IT编程>开发语言>Java > java调用c程序通信示例代码

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

2019年07月22日  | 移动技术网IT编程  | 我要评论

复制代码 代码如下:

//===============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;
}

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网