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\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之间的通信的更多相关文章
- android中四大组件之间相互通信
好久没有写有关android有关的博客了,今天主要来谈一谈android中四大组件.首先,接触android的人,都应该知道android中有四大组件,activity,service,broadca ...
- angularJS中directive与directive 之间的通信
上一篇讲了directive与controller之间的通信:但是我们directive与directive之间的通信呢? 当我们两个directive嵌套使用的时候怎么保证子directive不会被 ...
- 使用reflux进行react组件之间的通信
前言 组件之间为什么要通信?因为有依赖. 那么,作为React组件,怎么通信? React官网说, 进行 父-子 通信,可以直接pass props. 进行 子-父 通信,往父组件传给子组件的函数注入 ...
- Fragment之间的通信(四)
自定义两个fragment的布局和java类. 在mainactivity中引用布局文件 在其中的一个fragment中的控件上添加监听,获取到另一个fragment中控件的内容,展示出来完成frag ...
- react native 之子组件和父组件之间的通信
react native开发中,为了封装性经常需要自定义组件,这样就会出现父组件和子组件,那么怎么在父组件和子组件之间相互通信呢,也就是怎么在各自界面push和pop.传值. 父组件传递给子组件: 父 ...
- js组件之间的通信
应用场景: 1.在刷微博的时候,滑到某个头像上,会出现一张usercard(用户名片), 微博列表区有这个usercard, 推荐列表也有这个usercard,评论区也有. 2.在网上购物时,购物车安 ...
- react8 组件之间的通信
<body><!-- React 真实 DOM 将会插入到这里 --><div id="example"></div> <!- ...
- Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
以下内容为原创,转载请注明:http://www.cnblogs.com/tiantianbyconan/p/3364728.html 我前两天写过一篇博客<Android使用Fragment来 ...
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
以下内容为原创,转载请注明:http://www.cnblogs.com/tiantianbyconan/p/3360938.html 如新浪微博下面的标签切换功能,我以前也写过一篇博文(http:/ ...
随机推荐
- 【Qt】Qt Creator介绍【转】
简介 Qt Creator是使用Qt开发的IDE.Qt支持Windows.Linux/Unix.Mac OS X.Android.BlackBerry.QNX等多种平台,Qt Creator为不同平台 ...
- AngularJS(11)-API
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- CSS居中的实现用法实例
转载的一篇文章,讲解css内容居中的. 网上有关css 居中的文章不胜枚举,不过大多没有做系统的总结.这里分享的这篇有关css居中的文章,个人感觉不错,值得收藏. 一.水平居中1,将元素水平居中(us ...
- 解析php mysql 事务处理回滚操作(附实例)
其实用PHP来处理mysql的事务回滚并不难,下面小编就详细的为大家介绍一下.相信大家看完之后都知道如何使用 很多新手在进行项目过程中,会碰到这样一种情况,如:论坛扣币项目中,用户支付论坛币的时候如果 ...
- 编写php拓展实例--slime项目(用户登录会话类)
最近公司换了yaf框架,突然对用c实现php拓展感兴趣了,如果一个功能已经很稳定很成熟而且用的地方很多,那么我们就可以尝试用拓展实现(不一定每种情况都可以写成拓展),写成拓展后就不用每次用都包含一 ...
- hive中简单介绍分区表
所介绍内容基本上是翻译官方文档,比较肤浅,如有错误,请指正! hive中创建分区表没有什么复杂的分区类型(范围分区.列表分区.hash分区.混合分区等).分区列也不是表中的一个实际的字段,而是一个或者 ...
- Oracle使用%type类型的变量输出结果
使用%type关键字可以声明一个与指定列名称相同的数据类型,他通常紧跟在指定列名的后面. 使用%type的2个好处: 1.用户不必查看表中各个列的数据类型,就可以确保所定义的变量能够存储检索的数据. ...
- C# 时间戳
C# 时间与时间戳互转 13位 /// <summary> /// 将c# DateTime时间格式转换为Unix时间戳格式 /// </summary> /// <pa ...
- 【Go】为什么用go; Golang Erlang 前世今生
给自己一条退路,再次比较Erlang和Golang 2014-6-28 陈叶皓 chenyehao@gmail.com 雨天的周末,适合码字的时节... 一年前我开始学习go语言的时候,如获至宝,既有 ...
- win2008修改最大远程桌面连接数
win2008修改最大远程桌面连接数 运行——gredit.msc——管理模板——windows组件——远程桌面服务——远程桌面回话主机——连接——限制连接的数量——修改为999999