本人用delphi编写一个聊天程序总出错(50分)

H

hany

Unregistered / Unconfirmed
GUEST, unregistred user!
本人用delphi编写一个聊天程序类似demos的,只是我在局域网上
分为客户端和服务器端,但当客户端请求连接,连上以后在服务器端
出现错误信息‘Socket API 'getpeername error'’大概是这样
不知是否有什么该注意的我没注意到,因在下是编程新手一时不知
怎么办。请指教。
 
试试只使用ip地址,而不用主机名,
要用主机名,需要设定DNS或在hosts
中加入。
 
ip地址也不好使
 
把你程序的关键部分贴出来看看
 
客户端:
两个memo,memohe,memoyou
三个button,buttonconnect,buttoncancel,buttonclose
意义同button名字
unit UnitChat;

interface

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

type
TFormChat = class(TForm)
Label1: TLabel;
Label2: TLabel;
MemoHe: TMemo;
MemoYou: TMemo;
Label3: TLabel;
EditHeHost: TEdit;
ButtonConnect: TButton;
Label4: TLabel;
Label5: TLabel;
EditHePost: TEdit;
ClientSocketChat: TClientSocket;
StatusBarChat: TStatusBar;
ButtonCencel: TButton;
ButtonClose: TButton;
procedure ButtonConnectClick(Sender: TObject);
procedure ClientSocketChatConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketChatRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketChatError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure MemoYouKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure ButtonCloseClick(Sender: TObject);
procedure ButtonCencelClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
FormChat: TFormChat;

implementation

{$R *.DFM}

procedure TFormChat.ButtonConnectClick(Sender: TObject);
begin
ClientSocketChat.Host :=EditHeHost.Text ;
ClientSocketChat.Port :=strtoint(EditHePost.Text) ;
StatusBarChat.SimpleText := '正在连接' + EditHeHost.Text
+ ' 端口:' + EditHePost.Text;
ClientSocketChat.Open ;
ButtonConnect.Enabled:=False;
ButtonCencel.Enabled:=true;
end;

procedure TFormChat.ClientSocketChatConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBarChat.SimpleText := '已经连接' + EditHeHost.Text
+ ' 端口:' + EditHePost.Text;
end;

procedure TFormChat.ClientSocketChatRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
MemoHe.Lines.Add (ClientSocketChat.Socket.ReceiveText);
end;

procedure TFormChat.ClientSocketChatError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
StatusBarChat.SimpleText := '连接' + EditHeHost.Text
+ ' 端口:' + EditHePost.Text + '失败';
end;

procedure TFormChat.MemoYouKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_Return then
ClientSocketChat.Socket.SendText(MemoYou.Lines[MemoYou.Lines.Count - 1]);
end;

procedure TFormChat.ButtonCloseClick(Sender: TObject);
begin
ClientSocketChat.Close ;
Application.Terminate ;
end;

procedure TFormChat.ButtonCencelClick(Sender: TObject);
begin
ClientSocketChat.Close ;
ButtonConnect.Enabled:=true;
ButtonCencel.Enabled:=false;
end;

procedure TFormChat.FormCreate(Sender: TObject);
begin

end;

end.
服务器端:
unit UnitChat;

interface

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

type
TFormChat = class(TForm)
Label1: TLabel;
Label2: TLabel;
MemoHe: TMemo;
MemoYou: TMemo;
Label3: TLabel;
EditHeHost: TEdit;
ButtonStart: TButton;
Label4: TLabel;
Label5: TLabel;
EditHePost: TEdit;
StatusBarChat: TStatusBar;
ServerSocketChat: TServerSocket;
ButtonStop: TButton;
ButtonClose: TButton;
procedure ButtonStartClick(Sender: TObject);
procedure ServerSocketChatAccept(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocketChatClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure MemoYouKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure ButtonStopClick(Sender: TObject);
procedure ButtonCloseClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
FormChat: TFormChat;

implementation

{$R *.DFM}

procedure TFormChat.ButtonStartClick(Sender: TObject);
begin
if EditHePost.Text<>'' then
begin
ServerSocketChat.Port :=StrToInt(EditHePost.Text);
ServerSocketChat.Open ;
ButtonStart.Enabled :=False;
ButtonStop.Enabled :=True;
end;
end;

procedure TFormChat.ServerSocketChatAccept(Sender: TObject;
Socket: TCustomWinSocket);
begin
EditHeHost.Text := ServerSocketChat.Socket.RemoteHost ;
StatusBarChat.SimpleText := '已经连接' + EditHeHost.Text
+ ' 端口:' + EditHePost.Text;
end;

procedure TFormChat.ServerSocketChatClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
MemoHe.Lines.Add (ServerSocketChat.Socket.ReceiveText);
end;

procedure TFormChat.MemoYouKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_Return then
ServerSocketChat.Socket.Connections[0].SendText(MemoYou.Lines
[MemoYou.Lines.Count - 1]);
end;

procedure TFormChat.ButtonStopClick(Sender: TObject);
begin
ServerSocketChat.Close ;
ButtonStart.Enabled :=true;
ButtonStop.Enabled :=False;

end;

procedure TFormChat.ButtonCloseClick(Sender: TObject);
begin
ServerSocketChat.Close ;
Application.Terminate ;
end;

procedure TFormChat.FormCreate(Sender: TObject);
begin

end;

end.
 
如果你装了MicroSoft Proxy Client,那出现这种情况一点都不奇怪,但我并不知道
解决的方法.
 
你的Client端是正确的,Server端有两个错误:

1.
procedure TFormChat.ServerSocketChatAccept(Sender: TObject;
Socket: TCustomWinSocket);
begin
EditHeHost.Text := ServerSocketChat.Socket.RemoteHost ;
//^^^^^^^^^^^^^^^^^
//删去上面几个字
StatusBarChat.SimpleText := '已经连接' + EditHeHost.Text+ ' 端口:' + EditHePost.Text;
end;

2.
procedure TFormChat.ServerSocketChatClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
MemoHe.Lines.Add (ServerSocketChat.Socket.ReceiveText);
//^^^^^^^^^^^^^^^^^
//删去上面几个字
end;

注意:
这里Socket不是ServerSocketChat,而是Client端的Socket,
也就是上面两个过程的后一个参数。
 
谢谢大家的回答!!
请问dubhe您能详细解释一下吗,您的回答是正确的!
 
是不是ServerSocketChat.Socket和socket是两个东东啊?
我也想知道正确答案啊!!
 
的确是两个东东。

在这里需要用到的不是ServerSocketChat.Socket,而是Client端的Socket连接。
也就是这两个事件的第二个参数。

这两个事件都属于TSocketNotifyEvent类型。类型定义如下:
type TSocketNotifyEvent = procedure (Sender: TObject; Socket: TCustomWinSocket) of object;

关于参数的说明是这样的:
When the event handler belongs to a client Windows socket object, these two parameters are the same. For server Windows socket objects, the Sender parameter represents the listening connection while the Socket parameter represents a client connection.

上面的内容是从Delphi的帮助中Copy出来的。要是不明白,就看看帮助吧。
 
顶部