Client和Server无法通讯,有什么问题请指正!(100分)

  • 主题发起人 主题发起人 cfjjj
  • 开始时间 开始时间
STOP! 偏题了。[:D]
 
就是啊,大家讨论这么热烈,还是没有人能指出我开始贴出的程序的错误来。
指出哪个地方错了,应该怎么改,我们的知识水平就得到提高了,下次也知道
怎么做了!现在争论C/S好象没有什么太大的意义吧!
 
这个程序被你改的太糟了,好多重复代码.你在client端没有定义端口号,怎么通讯?
加上:
const
UDPPORT = 55555
就行了.
 
仔细看你的程序client和server的端口号不一致.55555,55554
 
谁说我没定义,一开始不就定义了吗,只不过我写的是55554。后来我按大家说的,改成了
55555,结果还是没戏!
 
真是皇天不负苦心人,原来什么问题也没有,根本不关socket的事,看见这句了没有
FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(EditServerIP.text));
将EditServerIP.text改成frmmain.EditServerIP.text之后,一切问题迎刃而解。
现在,我把成功的程序再放上来,给将来的弟兄们看一看。
服务器端:
unit Unit1;

interface

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

const
WM_SOCK = WM_USER + 1; //自定义windows消息
UDPPORT = 55555; //设定UDP端口号

type
TFrmmain = class(TForm)
BtnStart: TButton;
BtnStop: TButton;
BtnExit: TButton;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure BtnStartClick(Sender: TObject);
procedure BtnStopClick(Sender: TObject);
procedure BtnExitClick(Sender: TObject);
private
{ Private declarations }
s: TSocket;
addr: TSockAddr;
FSockAddrIn : TSockAddrIn;
//利用消息实时获知UDP消息
procedure ReadData(var Message: TMessage);
message WM_SOCK;
public
{ Public declarations }
end;

var
Frmmain: TFrmmain;

implementation

{$R *.dfm}



procedure TFrmmain.FormCreate(Sender: TObject);
begin
frmmain.BtnStart.Visible:=true;
btnstop.Visible:=false;
end;

procedure TFrmmain.BtnStartClick(Sender: TObject);
var
TempWSAData: TWSAData;
begin
// 初始化SOCKET
if WSAStartup($101, TempWSAData)=1 then
showmessage('StartUp Error!');

s := Socket(AF_INET, SOCK_DGRAM, 0);
if (s = INVALID_SOCKET) then //Socket创建失败
begin
showmessage(inttostr(WSAGetLastError())+' Socket创建失败');
CloseSocket(s);
// exit;
end;
//发送方SockAddr绑定
addr.sin_family := AF_INET;
addr.sin_addr.S_addr := INADDR_ANY;
addr.sin_port := htons(UDPPORT);
if Bind(s, addr, sizeof(addr)) <> 0 then
begin
showmessage('bind fail');
end;
WSAAsyncSelect(s, frmmain.Handle , WM_SOCK, FD_READ);
//接收端SockAddrIn设定
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(UDPPORT);

frmmain.BtnStart.Visible:=false;
frmmain.BtnStop.Visible:=true;
end;

procedure TFrmmain.BtnStopClick(Sender: TObject);
begin
CloseSocket(s);
frmmain.BtnStart.Visible:=true;
frmmain.BtnStop.Visible:=false;
end;

procedure Tfrmmain.ReadData(var Message: TMessage);
var
buffer: Array [1..4096] of char;
len: integer;
flen: integer;
Event: word;
value: string;
begin
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Port := htons(UDPPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(s, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
value := copy(buffer, 1, len);
if value='Daytime' then
begin
value:=datetimetostr(now);
frmmain.Edit1.Text:=inet_ntoa(FSockAddrIn.sin_addr)+ '正在访问!';
//inttostr(getpeername(s,FSockAddrIn,flen))+'正在访问!';
len := sendto(s, value[1], Length(value), 0, FSockAddrIn, sizeof(FSockAddrIn));
if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then
showmessage(inttostr(WSAGetLastError()));
if len = SOCKET_ERROR then
showmessage('send fail');
if len <> Length(value) then
showmessage('Not Send all');
end;
end;
end;

procedure TFrmmain.BtnExitClick(Sender: TObject);
begin
CloseSocket(s);
frmmain.Close;
end;

end.

客户端:
unit Unit1;

interface

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

const
WM_SOCK = WM_USER + 1; //自定义windows消息
UDPPORT = 55555; //设定UDP端口号

type
TFrmmain = class(TForm)
EditReturnData: TEdit;
BtnStart: TButton;
BtnExit: TButton;
EditServerIP: TEdit;
Label1: TLabel;
procedure BtnStartClick(Sender: TObject);
procedure BtnExitClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
s: TSocket;
addr: TSockAddr;
FSockAddrIn : TSockAddrIn;
//利用消息实时获知UDP消息
procedure ReadData(var Message: TMessage);
message WM_SOCK;
public
{ Public declarations }
procedure SendData(Content: String);
end;

var
Frmmain: TFrmmain;

implementation

{$R *.dfm}

procedure TFrmmain.FormCreate(Sender: TObject);
var
TempWSAData: TWSAData;
begin
// 初始化SOCKET
if WSAStartup($101, TempWSAData)=1 then
showmessage('StartUp Error!');

s := Socket(AF_INET, SOCK_DGRAM, 0);
if (s = INVALID_SOCKET) then //Socket创建失败
begin
showmessage(inttostr(WSAGetLastError())+' Socket创建失败');
CloseSocket(s);
// exit;
end;
//发送方SockAddr绑定
addr.sin_family := AF_INET;
addr.sin_addr.S_addr := INADDR_ANY;
addr.sin_port := htons(UDPPORT);
if Bind(s, addr, sizeof(addr)) <> 0 then
begin
showmessage('bind fail');
end;
WSAAsyncSelect(s, frmmain.Handle , WM_SOCK, FD_READ);
//接收端SockAddrIn设定
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(UDPPORT);
end;

procedure TFrmmain.BtnStartClick(Sender: TObject);
begin
senddata('Daytime');
end;

{procedure TFrmmain.Daytime(var Message: TMessage);
var
buffer: Array [1..4096] of char;
len: integer;
flen: integer;
Event: word;
value: string;
begin
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Port := htons(UDPPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(s, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
value := copy(buffer, 1, len);
form1.EditReturnData.Text :=value;
end;
end;
}
procedure Tfrmmain.ReadData(var Message: TMessage);
var
buffer: Array [1..4096] of char;
len: integer;
flen: integer;
Event: word;
value: string;
begin
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Port := htons(UDPPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(s, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
value := copy(buffer, 1, len);
frmmain.EditReturnData.Text:=value;
end;
end;

procedure Tfrmmain.SendData(Content: String);
var
value{,hostname}: string;
len: integer;
begin
FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(frmmain.EditServerIP.Text)); //INADDR_BROADCAST; //INADDR_BROADCAST = -1 ?
value := Content;
len := sendto(s, value[1], Length(value), 0, FSockAddrIn, sizeof(FSockAddrIn));
if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then
showmessage(inttostr(WSAGetLastError()));
if len = SOCKET_ERROR then
showmessage('send fail');
if len <> Length(value) then
showmessage('Not Send all');
end;
procedure TFrmmain.BtnExitClick(Sender: TObject);
begin
CloseSocket(s);
frmmain.Close;
end;
end.
其实客户端和服务器是一样的。只不过客户端是先发后听再收,服务器是先听后收再发。
谢谢各位的关心,有问题还会再来找各位富翁的!谢谢!!!!!!!!!
 
多人接受答案了。
 
>>只不过客户端是先发后听再收,服务器是先听后收再发。
这句话有问题,无论是client或server,收发都是没有一定的顺序的。client也可以先收。
 

Similar threads

I
回复
0
查看
686
import
I
I
回复
0
查看
1K
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部