// 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\n",recvBuf);
  memset(recvBuf,0,sizeof(recvBuf));
  recv(sockConn,recvBuf,sizeof(recvBuf),0);
  printf("%s\n",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:\华腾项目软件\sendmsg\a.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;

C++和pascal之间的通信的更多相关文章

  1. android中四大组件之间相互通信

    好久没有写有关android有关的博客了,今天主要来谈一谈android中四大组件.首先,接触android的人,都应该知道android中有四大组件,activity,service,broadca ...

  2. angularJS中directive与directive 之间的通信

    上一篇讲了directive与controller之间的通信:但是我们directive与directive之间的通信呢? 当我们两个directive嵌套使用的时候怎么保证子directive不会被 ...

  3. 使用reflux进行react组件之间的通信

    前言 组件之间为什么要通信?因为有依赖. 那么,作为React组件,怎么通信? React官网说, 进行 父-子 通信,可以直接pass props. 进行 子-父 通信,往父组件传给子组件的函数注入 ...

  4. Fragment之间的通信(四)

    自定义两个fragment的布局和java类. 在mainactivity中引用布局文件 在其中的一个fragment中的控件上添加监听,获取到另一个fragment中控件的内容,展示出来完成frag ...

  5. react native 之子组件和父组件之间的通信

    react native开发中,为了封装性经常需要自定义组件,这样就会出现父组件和子组件,那么怎么在父组件和子组件之间相互通信呢,也就是怎么在各自界面push和pop.传值. 父组件传递给子组件: 父 ...

  6. js组件之间的通信

    应用场景: 1.在刷微博的时候,滑到某个头像上,会出现一张usercard(用户名片), 微博列表区有这个usercard, 推荐列表也有这个usercard,评论区也有. 2.在网上购物时,购物车安 ...

  7. react8 组件之间的通信

    <body><!-- React 真实 DOM 将会插入到这里 --><div id="example"></div> <!- ...

  8. Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信

    以下内容为原创,转载请注明:http://www.cnblogs.com/tiantianbyconan/p/3364728.html 我前两天写过一篇博客<Android使用Fragment来 ...

  9. Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信

    以下内容为原创,转载请注明:http://www.cnblogs.com/tiantianbyconan/p/3360938.html 如新浪微博下面的标签切换功能,我以前也写过一篇博文(http:/ ...

随机推荐

  1. Ping N个IP测试网络连通性

    #-----------------------Smokeping移动节点-------------------##! /bin/bashecho "------------- Statin ...

  2. oracle创建用户,修改用户,删除用户等关于用户的

    --直接修改底层表 USER$ 更换用户名 1.windows 平台下运行 cmd 2.sqlplus /nolog 3.SQL> conn SYSTEM/123@ORCL as sysdba ...

  3. 用python实现哈希表

    哈哈,这是我第一篇博客园的博客.尝试了一下用python实现的哈希表,首先处理冲突的方法是开放地址法,冲突表达式为Hi=(H(key)+1)mod m,m为表长. #! /usr/bin/env py ...

  4. SQL Server 2008 远程过程调用失败

    今天在写程序的时候,突然间发现数据库连接不上了,打开管理器发现SQL2008出现这样的错误. 非常的郁闷,找了好多方法都没有解决,最后想想是不是应为安装vs2013中的SQL Server Expre ...

  5. 微软职位内部推荐-Android Developer

    微软近期Open的职位: Position: SDE II or Senior SDE -- Mobile Products Android/WP Contact Person: Winnie Wei ...

  6. 初涉Node.js

    Node.js的是建立在Chrome的JavaScript的运行时,可方便地构建快速,可扩展的网络应用程序的平台. Node.js使用事件驱动.非阻塞I/ O模型,是轻量级.高效.完美的跨分布式设备运 ...

  7. SQL Server数据库事务日志序列号(LSN)介绍

    原文:http://blog.csdn.net/tjvictor/article/details/5251463     日志序列编号(LSN)是事务日志里面每条记录的编号. 当你执行一次备份时,一些 ...

  8. 在云服务器搭建WordPress博客(四)WordPress的基本设置

    前面说了 如何安装WordPress,接下来我们需要快速熟悉WordPress,以及进行一些必要的基本设置. 开始设置之前,建议大家先点击一篇左边菜单栏的每一个选项,看看到底是做什么用的.下面开始说一 ...

  9. 从状态转移看:载波侦听多路访问/冲突避免(CSMA/CA)

    CSMA/CA是写入IEEE802.11的无线网络MAC层标准协议,相信看到这篇文章的读者都知道它是用来做什么的.但许多短文对这个协议的解释都有所缺乏,因此本文用状态转换图的形式详细说明协议的工作流程 ...

  10. VIM配置自动提示功能

        问题描述:                  使用VIM作为Linux下的IDE,但是VIM默认情况下不支持自动代码提示功能,因此希望安装插件实现自动提示功能,目前找到的自动提示工具,非常好用 ...