如何在使用clientsocket ,serversocket的C/S程序间传递多个变量?(200分)

  • 主题发起人 主题发起人 atomy
  • 开始时间 开始时间
A

atomy

Unregistered / Unconfirmed
GUEST, unregistred user!
看到的例子都是传递一个变量的,怎么也想不出传递多个变量的方法.而且服务端在收到变量
并处理完后发送处理完的的资料给刚才提交变量的客户端,如何实行?????
 
主要是下列3点.
1,使用socket通信的客户端与服务端相互传递多个包括不同内容的变量.
2,通过客户端发过来的变量,服务端对数据库里的信息进行对比.然后返回数据给客户端.
3,能断开不符合要求的某一个的连接.

很急,请各位大侠帮帮忙.我找了好多源代码都没有介绍这方面资料,关系到我现在的工作
问题,救救我!!
 
这么容易得分的问题都没人答我....
>___<
 
〉使用socket通信的客户端与服务端相互传递多个包括不同内容的变量.
参数的数量是你自己定义的啊?如果你只能穿一个参数,那么这个参数你可以传递数组
 
我就是不懂传送/接收的的代码如何写... >_<
 
定义一个结构,每次收发整个结构,通过分析结构中的各个成员内容来确定客户端与服务器
之间要做些什么。
例:
type
ComStruct = record
CommandType: Integer;
CommandCode: Integer;
ClientType: Integer;
end;

//客户端:
var
cs : ComStruct;
begin
cs.CommandType := 10001; //最好把这些值定义成常量,以便记忆
cs.CommandCode := 20001;
cs.ClientType := 30001;
ClientSocket.Socket.SendBuf(cs, SizeOf(cs));
end;

//服务器端(OnClientRead事件):
var
cs : ComStruct;
begin
Socket.ReceiveBuf(cs, SizeOf(cs));
case cs.CommandType of
10001: //do something
case cs.CommandCode of
20001: //...
end;
10002: //do something
end;
end;
 
怎么回事?
发送是成功的,收到的是乱码。
CS.Socket.SendBuf(testone,Sizeof(testone));//在这里可以查看到发送信息成功。

Socket.ReceiveBuf(testone,Sizeof(testone));//在这里收到的是乱码。


 
乱码?你使用string类型?如果使用了string类型,那么要指定长度:比如 string[100]
 
用Pchar类型
 
procedure ReadFields(RecordString: String; ArrayOfString: array of PString);
var I: Integer; Temp: string;
begin
Temp := RecordString;
for I := Low(ArrayOfString) to High(ArrayOfString) do
begin
ArrayOfString^ := Copy(Temp, 1, Pos('|', Temp) - 1);
Delete(Temp, 1, Pos('|', Temp));
end;
end;

var
Id, FUserName, FPassword: string;
ReceiveText := ClientSocket.ReceiveText;
if Trim(ReceiveText) = '' then Exit;
ReadFields(ReceiveText, [@Id, @FUserName, @FPassword]);

数组是动态的,根据特定字符分割,接收回来后可以根据顺序依次取得,如果后面的不需要,也可以不定义变量
最好把变量设成结构

 
only you 啊。
我用pchar
什么都收不到啊。
先说明,如果是传符串是可以,是传record的时候不可以。
type
test=record
userid:Pchar;
end;

testone:test;
testone.userid:='peyton';

CS.Socket.SendBuf(testone,Sizeof(testone));// 传过去了。
收不到???
testone:test;
Socket.ReceiveBuf(testone,Socket.ReceiveLength) ;

 
如果是如下面这样收一个客户发过来的字符串是可以收到的。
s := Socket.ReceiveText;
 
乱码?你在ComStruct里面使用了string类型?如果使用了string类型,那么要指定长度:比如 string[100]
 
我与zeusangel的情况一样,只能传字符串,不能传数组.
 
注意:你必须正确地指定收发的数据的尺寸,才能正确的收发
为什么发送字符串会收不到呢?因为字符串实际上是由一个指针指向的,在用SizeOf来判断
一个字符串的大小时,返回的总是字符串首指针的大小,因此你发过去的只是这个指针所指
向的地址,收到的当然就不会是正确的数据了。
不信你可以试试,按照这样的定义:
type
test=record
userid:Pchar;
end;
看看SizeOf(test)返回的是多少?肯定是4!不管多长的一串字符,你都只发出了其指针地
址,这就是用SendBuf来发送的结果。
所以,如果你要发送的是一个字符串,就应该用Length(),来决定发送的长度,而不是用
SizeOf,这也就是SendText的密秘了:它实际上是调用SendBuf来发送数据的,只不过在发送
前已经用Length()函数获取了要发送的字符串的长度。

由于静态数组是已经分配了内存的,所以可以直接用SizeOf()来判断其实际大小。用SendBuf
来发送静态数组是安全没有问题的,实际上SendBuf可以发送任何类型的数据,关键是你要清
楚将来发送的数据的确切大小。
 
但怎么定义
type
test=record
userid:Pchar;
end;
的长度?
"关键是你要清
楚将来发送的数据的确切大小。"这又怎么去做?
还请帮帮忙。
 
请各位谁会的帮个忙,我出两百分谢谢你啦。
另外要问的是
Tserversocket and Tclientsocket


TTcpclient and TTcpserver 是什么不同呢?
 
zeusangel:
我也要碰到这个问题了,如果有好的建议就发MAIL给我
先谢过了
 
如果你要把发送的数据定义在一个结构中,就应该把字符串定义为字符数组,这样才可以
通过SizeOf来获取结构的真实大小。
(我本不想把代码贴出来污染版面的……)
//服务器端代码:需要在窗体上放一个TServerSocket,两个TButton,一个TMemo
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
ServerSocket1: TServerSocket;
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
const
dim = 2048;
var
ar: array[1..dim] of Integer;
i,sz,rs: Integer;
begin
sz := SizeOf(ar);
rs := Socket.ReceiveBuf(ar, sz);
if (rs>0) then
begin
for i:=0 to dim do
Memo1.Lines.Add(IntToStr(ar));
end
else
ShowMessage('接收失败!');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ServerSocket1.Open;
Caption := 'Socket服务器启动';
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ServerSocket1.Close;
Caption := 'Socket服务器关闭';
end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add('接收到来自'+Socket.RemoteAddress+'的客户端连接');
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add('客户端'+Socket.RemoteAddress+'断开连接');
end;

end.

//客户端代码,需要在窗体上放一个TServerSocket,两个TButton,一个TMemo
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp, ExtCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
ClientSocket1: TClientSocket;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.Open;
end;

procedure TForm1.Button2Click(Sender: TObject);
const
dim = 2048;
var
ar: array[1..dim] of Integer;
i,rs,sz: Integer;
begin
for i:=1 to dim do
ar := i;

sz := SizeOf(ar);
rs := ClientSocket1.Socket.SendBuf(ar, sz);
if (rs>=sz) then
begin
ShowMessage('发送成功!');
for i:=1 to dim do
Memo1.Lines.Add(IntToStr(ar));
end
else
ShowMessage('发送失败!');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ClientSocket1.Close;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add('连接到服务器:'+Socket.RemoteAddress);
end;

procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add('从服务器'+Socket.RemoteAddress+'断开连接');
end;

end.
 
看了一下源文件,发现TTcpClient和TTcpServer是一套兼容Kylix的TCP/IP控件(奇怪的是
怎么不放在控件面板上?),在用法上应该和TClientSocket/TServerSocket差别不太,在
Windows下实现也是调用的Winsock函数,在Linux下自然用的也是Berkeley Socket函数了。
 
后退
顶部