现在的位置: 首页 > 综合 > 正文

c++builer与java之间的socket通信

2012年08月06日 ⁄ 综合 ⁄ 共 6354字 ⁄ 字号 评论关闭

c++builer与java之间的socket通信
  C++builer与java都提供了功能丰富的socket控件/类。这里将实现c++builer与java之间的socket通信,
能够使双方互相发送信息。
  在C++builer里,我们采用 ServerSocket控件做为服务器端,java里采用Socket类做为客户端。
本示例中互相发送的都为结构体,在C++builer里定义为
typedef struct
{
  int int1;
  float f;
  char  ch[20];
  double d;
} TMyMsg;

java里发送部分是直接用的DataOutputStream 的writeXXX方法,当然也可以用内部类转换成byte[]进行发送。

源代码如下:
C++builer服务器端

Unit1.cpp

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include <winsock.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
ServerSocket1->Active = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::BtnSendClick(TObject *Sender)
{
 //发送的数据要进行字节序转换.
 TMyMsg sendmsg;
 sendmsg.int1 = htonl(30);
 sendmsg.f = ntohf(12.345);
 strcpy(sendmsg.ch,"测试数据!");
 sendmsg.d = ntohd(67.890);
 ServerSocket1->Socket->Connections[0]->SendBuf(&sendmsg, sizeof(TMyMsg));

}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormShow(TObject *Sender)
{
 MemoSend->Lines->Add("int : 30");
 MemoSend->Lines->Add("float : 12.345");
 MemoSend->Lines->Add("char [20] : 测试数据!");
 MemoSend->Lines->Add("double : 67.890");
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
      TCustomWinSocket *Socket)
{
 //接收的数据字节序转换
  TMyMsg remsg;
  Socket->ReceiveBuf(&remsg,sizeof(TMyMsg));
  int int1 = ntohl(remsg.int1);
  float f = ntohf(remsg.f);
  char  *ch = new char[20];
  strcpy(ch,remsg.ch);
  AnsiString sch = StrPas(ch);
  double d = ntohd(remsg.d);
  delete [] ch;

  MemoRec->Lines->Add(int1);
  MemoRec->Lines->Add(f);
  MemoRec->Lines->Add(sch.Trim());
  MemoRec->Lines->Add(d);
}
//---------------------------------------------------------------------------

Unit1.h

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ScktComp.hpp>
#pragma pack(1)  //字节对齐

//---------------------------------------------------------------------------
typedef struct
{
  int int1;
  float f;
  char  ch[20];
  double d;
} TMyMsg;
//---------------------------------------------------------------------------
//ntohf 与ntohd函数为网上收录
float ntohf(float f)
{
  unsigned char *p, p0, p1;
  if(ntohs(1) ==1) return f;
  p =(unsigned char *)&f;
  p0 =p[0];
  p1 =p[1];
  p[0] =p[3];
  p[3] =p0;
  p[1] =p[2];
  p[2] =p1;
  return f;
}
//---------------------------------------------------------------------------
double ntohd(double d)
{
  unsigned char *p, p0, p1, p2, p3;
  if(ntohs(1) ==1) return d;
  p =(unsigned char *)&d;
  p0 =p[0];
  p1 =p[1];
  p2 =p[2];
  p3 =p[3];
  p[0] =p[7];
  p[7] =p0;
  p[1] =p[6];
  p[6] =p1;
  p[2] =p[5];
  p[5] =p2;
  p[3] =p[4];
  p[4] =p3;
  return d;
}
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
    TServerSocket *ServerSocket1;
    TButton *Button1;
    TLabel *Label1;
    TMemo *MemoSend;
    TLabel *Label2;
    TMemo *MemoRec;
    TButton *BtnSend;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall BtnSendClick(TObject *Sender);
    void __fastcall FormShow(TObject *Sender);
    void __fastcall ServerSocket1ClientRead(TObject *Sender,
          TCustomWinSocket *Socket);
private: // User declarations
public:  // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

java客户端

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

import java.io.*;
import java.net.*;

/*
 * 创建日期 2006-5-10
 *
 * TODO 要更改此生成的文件的模板,请转至
 * 窗口 - 首选项 - Java - 代码样式 - 代码模板
 */

/**
 * @author zwx
 *
 * TODO 要更改此生成的类型注释的模板,请转至 窗口 - 首选项 - Java - 代码样式 - 代码模板
 */
public class SocketClientDemo extends JFrame {
 int port = 2345;
 String host = "localhost";
 Socket socket;
 JButton jbConnect = new JButton("连接");
 JButton jbSend = new JButton("发送");
 JTextArea jTASend = new JTextArea(7, 10);
 JTextArea jTARec = new JTextArea(7, 10);

 public SocketClientDemo() {
  super("客户端");
  Container cp = this.getContentPane();
  cp.setLayout(new FlowLayout());
  cp.add(jbConnect);
  cp.add(jbSend);
  jbSend.addActionListener(jbSendAL);  //发送按钮
  jbConnect.addActionListener(jbConnectAL);  //连接按钮

  cp.add(jTARec);
  jTARec.append("接收的内容");
  cp.add(jTASend);
  jTASend.append("发送的内容");
  jTASend.append("/nint : 88");
  jTASend.append("/nfloat : 77.66");
  jTASend.append("/nString : From JAVA");
  jTASend.append("/ndouble : 23.45");

  this.setSize(250, 200);
  this.setLocation(100, 100);
  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  this.setVisible(true);

 }

 public static void main(String[] args) {
  new SocketClientDemo();
 }

 ActionListener jbConnectAL = new ActionListener() {

  public void actionPerformed(ActionEvent e) {
   try {
    //实例化Socket ,并接收C++builder服务器端发送的数据
    socket = new Socket(InetAddress.getByName(host), port);
    DataInputStream in = new DataInputStream(socket .getInputStream());
    int int1 = in.readInt();
    float f = in.readFloat();
    byte[] buffer = new byte[20];
    in.read(buffer);
    String ch = new String(buffer);
    double d = in.readDouble();

    jTARec.append("/n" + Integer.toString(int1));
    jTARec.append("/n" + Float.toString(f));
    jTARec.append("/n" + ch.trim());
    jTARec.append("/n" + Double.toString(d));
   }//try
   catch (IOException ex) {
    ex.printStackTrace();
   }

  }

 };

 ActionListener jbSendAL = new ActionListener() {

  public void actionPerformed(ActionEvent e) {
   try {
    //发送给服务器端
    DataOutputStream out = new DataOutputStream(socket.getOutputStream());

    int int1 = 88;
    float f = (float) 77.66;
    String ch = "From JAVA";
    double d = 23.45;
   
    out.writeInt(int1);
    out.writeFloat(f);
    byte[] buf = new byte[20];
    System.arraycopy(ch.getBytes(),0,buf,0,ch.length());
    out.write(buf,0,buf.length);
    out.writeDouble(d);
    
   }//try
   catch (IOException ex) {
    ex.printStackTrace();
   }

  }

 };

}

由于c/c++语言编的程序的数据存储顺序跟编译平台机器的CPU有关,而java程序则采用大字节序,网络字节序也采用大字节序存储,
因此C++builer的发送与接收函数都要先把数据进行字节序转换。另外还要注意字节对齐问题,本例中C++builder的结构体是一字节对齐。
运行界面如下:

 

    

运行时先启动服务器端,点击“启动服务器端”按钮。再启动客户端,选连接,先发送服务端的数据,再发送客户端的数据。关闭时先关闭服务器端。

有任何问题,欢迎指正。 E-mail:weixing979@163.com

抱歉!评论已关闭.