zoukankan      html  css  js  c++  java
  • C++和pascal之间的通信

    // MyFirst.cpp : 定义控制台应用程序的入口点。
    //

    #include "stdafx.h"
    #include "Winsock2.h"
    #pragma comment(lib,"ws2_32.lib")


    int _tmain(int argc, _TCHAR* argv[])
    {
        WORD wVersionRequested;
     WSADATA wsaData;
     int err;

     wVersionRequested = MAKEWORD(1,1);

     err = WSAStartup(wVersionRequested,&wsaData);
     if (err!=0)
     {
      return 0;
     }

     if (LOBYTE(wsaData.wVersion)!=1||
      HIBYTE(wsaData.wVersion)!=1)
     {
      WSACleanup();
      return 0;
     }
     SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);

     SOCKADDR_IN addrSrv;
     addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
     addrSrv.sin_family=AF_INET;
     addrSrv.sin_port=htons(5101);

     bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

     listen(sockSrv,5);

     SOCKADDR_IN addrClient;
     int len=sizeof(SOCKADDR);
     while(1)
     {
      SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
      char sendBuf[100];
        // sprintf_s(sendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));
      /*send(sockConn,sendBuf,strlen(sendBuf)+1,0);*send函数是将指定长度的数据复制到TCP的系统缓冲区,然后系统缓冲区负责发送流数据到接收端的缓冲区
                   recv负责从缓冲区复制数据到指定存储地址字节不一样又没事的,recv每次不一定接收固定的数据的*/
      char recvBuf[100];
      memset(recvBuf,0,sizeof(recvBuf));
      recv(sockConn,recvBuf,sizeof(recvBuf),0);
      printf("%s ",recvBuf);
      memset(recvBuf,0,sizeof(recvBuf));
      recv(sockConn,recvBuf,sizeof(recvBuf),0);
      printf("%s ",recvBuf);
      closesocket(sockConn);}
       
     return 0;
    }

    网上找的一段代码用C++重写了一遍然后用pascal写的客户端发送;

    发现总是无法接受到正常的数据,在经过N边检查之后,才明白。

    问题出现在客户端发送哪里有一个数据大小验证。

    unit uSendMsg;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,IdTCPClient,WinSock, IdBaseComponent, IdComponent,
      IdTCPConnection;

    type
      TFSendMsg = class(TForm)
        btnsend: TButton;
        Edit1: TEdit;
        Edit2: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Button1: TButton;
        Memo1: TMemo;
        Label3: TLabel;
        Edit3: TEdit;
        Label4: TLabel;
        Button2: TButton;
        dlg: TOpenDialog;
        procedure btnsendClick(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Memo1Click(Sender: TObject);
        procedure Edit3Click(Sender: TObject);
      private
        { Private declarations }
        client: TIdTCPClient;
        procedure sendSplitText(client: TIdTCPClient; s: String);
        Procedure SendFile(IFileName:string);
      public
        { Public declarations }
      end;

    var
      FSendMsg: TFSendMsg;

    implementation
    uses IdGlobal,IniFiles;
    {$R *.dfm}

    procedure TFSendMsg.btnsendClick(Sender: TObject);
    var
      iLength: Integer;
      s,s1,sSendText: String;
      flag: Boolean;
      aText: string;
    begin
      try
        if client.Connected() then
          client.Disconnect();
        if not client.Connected() then
        begin
          client.Host := trim(edit1.Text);
          client.Port := strtoint(trim(edit2.Text));
          client.Connect();
         // showmessage('连接成功');
        end;
      except on E: Exception do
      begin
          showMessage('连接主机失败,错误描述:'+ E.Message);
          exit;
      end;
      end;
      if not memo1.ReadOnly then
      begin
        try
           aText := trim(memo1.Text);
           if atext = '' then begin
              showmessage('No message send');
              exit;
           end;
           iLength := Length(aText);
           sSendText := intToStr(100000000 + iLength);
           Delete(sSendText, 1, 1);
           sSendText := sSendText + aText;
           if client.Connected() then
             sendSplitText(client,sSendText);
           showmessage('发送成功');
        except on E: Exception do
          ShowMessage('发送失败,错误描述:'+ E.Message);
        end;
      end else
      begin
      //  edit3.Text :=  'E:华腾项目软件sendmsga.txt';
        s1 := trim(edit3.Text);
        if s1 = '' then begin
          showmessage('请选择文件');
          exit;
        end;
        try
          if client.Connected() then
             sendfile(s1);
          showmessage('发送成功');
        except on E: Exception do
          ShowMessage('发送失败,错误描述:'+ E.Message);
        end;
      end;
    end;

    procedure TFSendMsg.Button1Click(Sender: TObject);
    begin
      close;
    end;

    procedure TFSendMsg.Button2Click(Sender: TObject);
    begin
      btnsend.Enabled := true;
      edit3.ReadOnly := false;
      memo1.ReadOnly := true;
      if dlg.Execute then
       edit3.Text := dlg.FileName;
    end;

    procedure TFSendMsg.Edit3Click(Sender: TObject);
    begin
      btnsend.Enabled := true;
      edit3.ReadOnly := false;
      memo1.ReadOnly := true;
    end;

    procedure TFSendMsg.FormShow(Sender: TObject);
    var
      s: string;
      ini: TIniFile;
    begin
      client := TIdTCPClient.Create(nil);
      s := ExtractFilePath(Application.ExeName)+'info.ini';
      if not fileExists(s) then
      begin
        ShowMessage('未找到配置文件'+ s);
        Application.Terminate;
        exit;
      end;
      ini := TIniFile.Create(s);
      Edit1.Text := ini.ReadString('info','ip','');
      Edit2.Text := IntToStr(ini.ReadInteger('info','port',0));
      Edit3.Text := ini.ReadString('info','path','');
      ini.Free;
    end;

    procedure TFSendMsg.Memo1Click(Sender: TObject);
    begin
      btnsend.Enabled := true;
      edit3.ReadOnly := true;
      memo1.ReadOnly := false;
    end;

    procedure TFSendMsg.SendFile(IFileName: string);
    var
      iFileHandle:integer;
      iFileLen,cnt:integer;
      buf:array[0..4096] of byte;
      mdata: TBytes;
      cc: array[0..3000] of char;
      bb: array[0..3000] of char;
      aa: array[0..3000] of char;
      sText,sSendText: string;
      i,iLength,isum: integer;
    begin
      iFileHandle:=FileOpen(IFileName,fmOpenRead);
      iFileLen:=FileSeek(iFileHandle,0,2);   //返回文件共多少个字符
      FileSeek(iFileHandle,0,0);  //指针指向文件开头

      FillChar(cc, sizeof(cc),0);
      cnt := FileRead(iFileHandle,cc,iFileLen);

      sSendText := intToStr(100000000 + iFileLen);
      Delete(sSendText, 1, 1);
      FillChar(aa, sizeof(aa),0);
      for i := 1 to 8 do
          aa[i-1] := sSendText[i];
      mdata := rawtobytes(aa, 8);
      client.Socket.Write(mdata);

      isum := 0;
      while iFileLen > 1000 do
      begin
        FillChar(bb, sizeof(bb),0);
        for i := 0 to 1000 - 1 do
          bb[i] := cc[i+isum];
        mdata := rawtobytes(bb, 1000);
        client.Socket.Write(mdata);
        isum := isum + 1000;
        iFileLen := iFileLen - 1000;
      end;

      if iFileLen > 0 then
      begin
        FillChar(bb, sizeof(bb),0);
        for i := 0 to iFileLen - 1 do
          bb[i] := cc[i+isum];
        mdata := rawtobytes(bb, iFileLen);
        client.Socket.Write(mdata);
      end;

      FileClose(iFileHandle);
    end;

    procedure TFSendMsg.sendSplitText(client: TIdTCPClient; s: String);
    var
      strStream:TStringStream;
      sText, s1: String;
      mdata: TBytes;
      cc: array[0..3000] of char;
      i: Integer;
    begin
      sText := s;
      FillChar(cc, sizeof(cc),0);
      for i := 1 to 18 do
          cc[i-1] := sText[i];
      mdata := rawtobytes(cc, 18);
      client.Socket.Write(mdata);
      Delete(sText,1,18);
      while Length(sText) > 1000 do
      begin
        s1 := Copy(sText,1,1000);
        FillChar(cc, sizeof(cc),0);
        for i := 1 to Length(s1) do
          cc[i-1] := s1[i];
        mdata := rawtobytes(cc, 1000);
        client.Socket.Write(mdata);
        Delete(sText,1,1000);
      end;
      if Length(sText) > 0 then
      begin
        FillChar(cc, sizeof(cc),0);
        for i := 1 to Length(sText) do
          cc[i-1] := sText[i];
        mdata := rawtobytes(cc, Length(sText));
        client.Socket.Write(mdata);
      end;
    end;

  • 相关阅读:
    vuex2.0 基本使用(4) --- modules
    vuex2.0 基本使用(3) --- getter
    vuex2.0 基本使用(2) --- mutation 和 action
    vuex2.0 基本使用(1) --- state
    git bash 下操作文件及文件夹命令
    SOFA 源码分析 — 负载均衡和一致性 Hash
    SOFA 源码分析 — 预热权重
    SOFA 源码分析— 事件总线
    SOFA 源码分析 — 自定义线程池原理
    SOFA 源码分析 — 链路数据透传
  • 原文地址:https://www.cnblogs.com/batman425/p/3164824.html
Copyright © 2011-2022 走看看