Socket发送消息? ( 积分: 50 )

  • 主题发起人 主题发起人 千禧狼龟
  • 开始时间 开始时间

千禧狼龟

Unregistered / Unconfirmed
GUEST, unregistred user!
我有一个记录:
TMyMsg=record
Msg:Cardinal;
MsgText:String;
我要用ClientSocket1.Socket发送Record到客户端,请问该怎么写啊?
 
我有一个记录:
TMyMsg=record
Msg:Cardinal;
MsgText:String;
我要用ClientSocket1.Socket发送Record到客户端,请问该怎么写啊?
 
啊?无人啊?高手帮帮忙了。。。
 
你用indy吧,下面的例子肯定适合

unit uServer;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ExtDlgs, IdBaseComponent, IdComponent, IdTCPServer;

type
TDataState = (dstNone, dstReceiving);
//Data对象用来保存一个连接的状态以及一些变量
TThreadData = class
private
FState: TDataState;
FFileSize: Integer;
FStream: TFileStream;
procedure SetState(const Value: TDataState);
procedure SetFileSize(const Value: Integer);
procedure SetStream(const Value: TFileStream);
public
constructor Create;
destructor Destroy; override;
property State : TDataState read FState write SetState;
property FileSize : Integer read FFileSize write SetFileSize;
property Stream : TFileStream read FStream write SetStream;
end;

type
TfmServer = class(TForm)
ProgressBar1: TProgressBar;
IdTCPServer1: TIdTCPServer;
procedure IdTCPServer1Connect(AThread: TIdPeerThread);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
private
{ Private declarations }
public
{ Public declarations }
end;

var
fmServer: TfmServer;

implementation

{$R *.dfm}

procedure TfmServer.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
AThread.Data := TThreadData.Create;
with AThread.Data as TThreadData do
begin
State := dstNone;
end;
end;

procedure TfmServer.IdTCPServer1Execute(AThread: TIdPeerThread);
var
aFileSize : Integer;
aFileName : String;
Buff : array[0..1023] of Byte;
ReadCount : Integer;
begin
with AThread.Data as TThreadData do
begin
if State = dstNone then
begin
if not AThread.Terminated and AThread.Connection.Connected then
begin
//读取文件名
aFileName := AThread.Connection.ReadLn(#13#10, 100);
if aFileName = '' then
Exit;


//返回确认文件传输标志
AThread.Connection.WriteLn;
//开始读取文件长度,创建文件
AThread.Connection.ReadBuffer(aFileSize, 4);
FileSize := aFileSize;
ProgressBar1.Max := FileSize;
Stream := TFileStream.Create(aFileName, fmCreate);
State := dstReceiving;
end

end;


if not AThread.Terminated and AThread.Connection.Connected then
begin
//读取文件流
repeat
if FileSize - Stream.Size > SizeOf(Buff) then
ReadCount := SizeOf(Buff)
else
ReadCount := FileSize - Stream.Size;
AThread.Connection.ReadBuffer(Buff, ReadCount);
Stream.WriteBuffer(Buff, ReadCount);
ProgressBar1.Position := Stream.Size;
Caption := IntToStr(Stream.Size) + '/' + IntToStr(FileSize);
Application.ProcessMessages;
until Stream.Size >= FileSize;
AThread.Connection.WriteLn('OK');
Stream.Free;
Stream := nil;
State := dstNone;
end;
end;
end;

{ TThreadData }

constructor TThreadData.Create;
begin
inherited;
Stream := nil;
end;

destructor TThreadData.Destroy;
begin
if Assigned(Stream) then
Stream.Free;
inherited;
end;

procedure TThreadData.SetFileSize(const Value: Integer);
begin
FFileSize := Value;
end;

procedure TThreadData.SetState(const Value: TDataState);
begin
FState := Value;
end;

procedure TThreadData.SetStream(const Value: TFileStream);
begin
FStream := Value;
end;

end.
 
String是一个地址,直接发送的时候,发的是String的地址,肯定不行。如果一定要使用,那你应该把他们拷贝到一个缓冲当中。或者使用定长字符串,如:array [0..1024] of char;
 
To:sonican 寻路
我不太明白你们的意思。
我的目的是将
TMyMsg=record
Msg:Cardinal;
MsgText:String;
这个结构体发送到服务器。
服务根据Msg来判执行什么方法或过程
比如:
my:TMyMsg;
my.Msg:=2000;
my.MsgText:='192.168.0.127';
把my这个结构体发送出去,服务器能够接收到这个结构体,就可以根据结构体内的设置进行判断并完成相应的操作。
----------------------------------
一个字符串比如:S:String='kk';
那么用:ClientSocket1.Socket.SendText(S);就可以发送出去了,
而服务器只需要:s:=ClientSocket1.Socket.ReceiveText;就能接收客户端发过来的消息
 
ClientSocket1.Socket。sendbuf
 
To:sonican 寻路
我不太明白你们的意思。
我的目的是将
TMyMsg=record
Msg:Cardinal;
MsgText:String;
这个结构体发送到服务器。
服务根据Msg来判执行什么方法或过程
比如:
my:TMyMsg;
my.Msg:=2000;
my.MsgText:='192.168.0.127';
把my这个结构体发送出去,服务器能够接收到这个结构体,就可以根据结构体内的设置进行判断并完成相应的操作。
----------------------------------
一个字符串比如:S:String='kk';
那么用:ClientSocket1.Socket.SendText(S);就可以发送出去了,
而服务器只需要:s:=ClientSocket1.Socket.ReceiveText;就能接收客户端发过来的消息

这个老兄说的对啊
 
TMyMsg=record
Msg:Cardinal;
MsgText:String;
end;
此结构中的String类型只是一个指针,你可以这样定义
TMyMsg=record
Msg:Cardinal;
MsgText:String[20];
end;
 
这需要两次发送,一次发送也行,稍候再说
var my:TMyMsg;
begin
try
client.Connect;
try
my.Msg:=2000;
client.writeinteger(my.Msg);
my.MsgText:='192.168.0.127';
client.writeln(my.MsgText);
client.readln; //此为服务端传送的结束标志
finally
client.disconnect;
end;
except //遇到连接及其它错误忽略待之
end;
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var my: TMyMsg;
begin
with AThread.Connection do begin
my.Msg := readinteger;
my.MsgText := readln;
...
writeln('完了');
end;
end;
 
用一次发送
var
my:TMyMsg;
pmy: ^TMyMsg;
p: pointer;
begin
try
client.Connect;
try
my.Msg:=2000;
my.MsgText:='192.168.0.127';
GetMem(p, sizeof(TMyMsg));
try
p := pmy;
pmy^ := my;
pmy := p;
client.writebuffer(p^, sizeof(TMyMsg));
finally
Freemem(p);
end;
client.readln; //此为服务端传送的结束标志
finally
client.disconnect;
end;
except //遇到连接及其它错误忽略待之
end;
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
my: TMyMsg;
pmy: ^TMyMsg;
p: pointer;
begin
with AThread.Connection do begin
Getmem(pmy);
try
p := pmy;
readbuffer(p^, sizeof(TMyMsg));
pmy := p;
my := pmy^;
finally
Freemem(pmy);
end;
...
writeln('完了');
end;
end;
 
写错了,Freemem(p)应是Freemem(pmy)
 
感谢各位。。。。。。。
 
后退
顶部