为什么我的程序在收到客户端的数据后在发送时会出错,请专家给我一个指点。(200分)

  • 主题发起人 主题发起人 rackrain
  • 开始时间 开始时间
R

rackrain

Unregistered / Unconfirmed
GUEST, unregistred user!
采用一个serversocket控件的type为stThreadBlocking,现在从客户端传来数据,采用线程来从后台的数据库中取出数sendstr(string类型),在发送后报错,请问是什么原因??
主程序如下:
procedure TForm1.ServerSocketGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
var mm:dataread;
begin
mm:=dataread.Create(ClientSocket);
end;
线程如下:
unit datareadthread;

interface

uses
Classes,ADODB,ComObj,Activex,idGlobal,SysUtils,Messages,windows,StdCtrls,ScktComp;

type
dataread = class(TThread)
private
{ Private declarations }
client_bank:TServerClientWinSocket;
sendstr:string;
clientsend:String;
FADOConnection:TADOConnection;
FADOQuery:TADOQuery;
protected
procedure QuerySend;
procedure WriteSend;
// procedure CancelSend;
procedure Execute; override;
public
constructor Create(const client:TServerClientWinSocket);
end;

implementation
uses dxsend;

{ dataread }
constructor dataread.Create(const client:TServerClientWinSocket);
begin
FreeOnTerminate:= True;
client_bank:=client;//
inherited Create(False);
end;

procedure dataread.Execute;
var Stream : TWinSocketStream;
buffer1: array[0 .. 69] of Char;
begin
Stream := TWinSocketStream.Create(client_bank, 3000);
FillChar(Buffer1,76, 0);
if Stream.WaitForData(2000) then //等待数据到来
begin
if Stream.Read(Buffer1,83) = 0 then //读数据
client_bank.Close
else
begin
//处理受到的数据
clientsend:=buffer1;
form1.SnEdit1.Text:=clientsend;
case strtoint(copy(clientsend,3,3)) of
110:QuerySend;//对后台的数据库进行操作
120:WriteSend;对后台的数据库进行操作
end;
client_bank.SendText(sendstr);//sendstr是要传给客户端的字符串
Stream.Free;
client_bank.Close;
end;
end
else
client_bank.Close;
end;//执行完后抱错,抱错如下:'external exception c000001D'
另外,采用阻塞方式时速度明显变慢,请问是什么原因??
 
看的晕,TServerSocket好像本身有线程处理的啊,这个问题最好让张无忌来回答。
 
的确看蒙了,帮你顶一下
 
好象应该不是client_bank.SendText(sendstr);//吧,应该用stream传数据是不是?
 
用indy试试看
 
To flying_bluebird,用stream传数据应该怎么写???
 
奇怪,既然都用TServerSocekt了,为什么不用非阻塞模式?既然都自己用类+多线程了,为什么不干脆直接用Winsock API?
 
To ego,我现在的问题是用stream传数据应该怎么写???
是不是stream.write(sendstr,length(sendstr)?
客户端收数程序如何写???
 
贴个例子你自己慢慢看吧 ^_^
Unit main;

Interface

Uses
Windows, SysUtils, Messages, Classes, Forms, ScktComp, Controls, StdCtrls,
Menus, Mask, Spin, ComCtrls, ExtCtrls;

Const
CM_IncCount = WM_USER + 1;

Type
TForm1 = Class(TForm)
ServerSocket: TServerSocket;
MainMenu: TMainMenu;
File1: TMenuItem;
ActiveItem: TMenuItem;
N1: TMenuItem;
Exit1: TMenuItem;
Panel1: TPanel;
Label1: TLabel;
CacheEdit: TSpinEdit;
Label2: TLabel;
PortEdit: TSpinEdit;
Label3: TLabel;
ThreadCount: TEdit;
Panel2: TPanel;
ListBox1: TListBox;
Panel3: TPanel;
StatusBar1: TStatusBar;
CharCount: TLabel;
Procedure ServerSocketGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
Var SocketThread: TServerClientThread);
Procedure FormCreate(Sender: TObject);
Procedure FormClose(Sender: TObject; Var Action: TCloseAction);
Procedure Exit1Click(Sender: TObject);
Procedure PortEditChange(Sender: TObject);
Procedure ActiveItemClick(Sender: TObject);
Procedure ServerSocketThreadEnd(Sender: TObject;
Thread: TServerClientThread);
Procedure ServerSocketThreadStart(Sender: TObject;
Thread: TServerClientThread);
Procedure CacheEditChange(Sender: TObject);
protected
Procedure CMIncCount(Var Msg: TMessage); message CM_IncCount;
public
End;

{ TFileServerThread }

TFileServerThread = Class(TServerClientThread)
public
Procedure ClientExecute; override;
End;

Var
Form1: TForm1;

Implementation

{$R *.DFM}

{ TFileServerThread }

Procedure TFileServerThread.ClientExecute;
Var
Data: Array[0..1023] Of char;
RecText: String;
SocketStream: TWinSocketStream;
Begin
While Not Terminated And ClientSocket.Connected Do
Try
SocketStream := TWinSocketStream.Create(ClientSocket, 30000);
Try
FillChar(Data, SizeOf(Data), 0);
If SocketStream.Read(Data, SizeOf(Data)) = 0 Then
Begin
// If we didn't get any data after xx seconds then close the connection
ClientSocket.SendText('Timeout on Server'+#13#10);
//Wait a little time to allow sending of text before disconnect
sleep(1);
ClientSocket.Close;
Terminate;
End;
RecText := Data;
If Length(RecText) > 2 Then
Delete(RecText, Pos(#13#10, RecText), 2); // Delete #13#10
If ClientSocket.Connected Then
Begin
ClientSocket.SendText(RecText);
SendMessage(Form1.Listbox1.Handle, LB_ADDSTRING, 0, Integer(PChar(RecText)));
PostMessage(Form1.Handle, CM_INCCOUNT, 0, 0);
End;
Finally
SocketStream.Free;
End;
Except
HandleException;
End;
End;

Procedure TForm1.ServerSocketGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
Var SocketThread: TServerClientThread);
Begin
// Create a new thread for connection
SocketThread := TFileServerThread.Create(False, ClientSocket);
ClientSocket.SendText('Welcome to Server'+#13#10);
End;

Procedure TForm1.FormCreate(Sender: TObject);
Begin
CacheEdit.Value := ServerSocket.ThreadCacheSize;
PortEdit.Value := ServerSocket.Port;
CharCount.Caption := '0';
ActiveItemClick(Nil);
End;

Procedure TForm1.FormClose(Sender: TObject; Var Action: TCloseAction);
Begin
ServerSocket.Close;
End;

Procedure TForm1.CMIncCount(Var Msg: TMessage);
Begin
CharCount.Caption := IntToStr(StrToInt(CharCount.Caption) + 1);
End;

Procedure TForm1.Exit1Click(Sender: TObject);
Begin
Close;
End;

Procedure TForm1.PortEditChange(Sender: TObject);
Begin
ServerSocket.Port := StrToInt(PortEdit.Text);
End;

Procedure TForm1.ActiveItemClick(Sender: TObject);
Begin
ServerSocket.Active := Not ServerSocket.Active;
ActiveItem.Checked := ServerSocket.Active;
If ServerSocket.Active Then
StatusBar1.SimpleText := 'Active'
Else
StatusBar1.SimpleText := 'InActive';
End;

Procedure TForm1.ServerSocketThreadEnd(Sender: TObject;
Thread: TServerClientThread);
Begin
ThreadCount.Text := IntToStr(StrToInt(ThreadCount.Text) - 1);
End;

Procedure TForm1.ServerSocketThreadStart(Sender: TObject;
Thread: TServerClientThread);
Begin
ThreadCount.Text := IntToStr(StrToInt(ThreadCount.Text) + 1);
End;

Procedure TForm1.CacheEditChange(Sender: TObject);
Begin
ServerSocket.ThreadCacheSize := CacheEdit.Value;
End;

End.
 
接受答案了.
 
后退
顶部