手机
当前位置:查字典教程网 >编程开发 >Java >java调用c程序通信示例代码
java调用c程序通信示例代码
摘要:复制代码代码如下://===============ClientStruct================#pragmapack(push...

复制代码 代码如下:

//===============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)

{

intlen;

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)

{

intlen;

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;

intlen ;

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;

}

【java调用c程序通信示例代码】相关文章:

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

希尔排序的算法代码

java 图片加水印实例代码

java poi读取excel操作示例(2个代码)

java正则表达式应用的实例代码

java 自动生成略缩图示例代码

java json 省市级联实例代码

java冒泡排序算法代码

java 实现约瑟夫环的实例代码

java数组遍历 删除remove(示例代码)

精品推荐
分类导航