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

这是一个示例代码,演示了如何使用C++编写程序,以便Java可以调用并发送数据。代码涉及Unicode与ASCII之间的转换、网络序与主机序的转换,以及数据结构的构建,主要用于实现Java与C之间的远程通信。
摘要由CSDN通过智能技术生成

#include

#include

#include

#include

#include

#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

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值