我遇到了一个网络编程问题,请帮忙! (50分)

  • 主题发起人 主题发起人 panpan-pan-0
  • 开始时间 开始时间
P

panpan-pan-0

Unregistered / Unconfirmed
GUEST, unregistred user!
我在学习wsa编程的时候写了一个小东西,为什么老是不可以呢?代码如下:
unit Unit1;

interface

uses
Windows,winsock, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,shellapi;
const async_event=500+1;
//async_event1=502;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
procedure my(var msg:tmsg);message async_event;
//procedure my1(var msg:tmessage);message async_event1;
public
{ Public declarations }
end;

var
Form1: TForm1;
wsadata:twsadata;
info:string;
bufsend,bufrecv:pchar;
skt,skt1:tsocket;
addr:tsockaddr;
re:integer;
sa:sockaddr_in;
implementation

{$R *.DFM}
procedure tform1.my(var msg:tmsg);
var flag:integer;
buf:pchar;
str:string;
i:integer;
begin
showmessage('lparam的值是:'+inttostr(msg.lparam));
showmessage('wparam的数值是:'+inttostr(msg.wParam));
re:=sizeof(addr);
//showmessage('accept');
showmessage('用于监听信息的socket:'+inttostr(skt));
//showmessage(inttostr(msg.wParam));;
flag:=wsagetselectevent(msg.wParam);
case flag of
fd_accept:
begin
skt1:=accept(0,@addr,@re);
if skt1=invalid_socket then
showmessage('用于传动信息的socket错误!');
showmessage('用户传送信息的socket:'+inttostr(skt1));
showmessage('发生的错误是:'+inttostr(wsagetlasterror));
end;
fd_read:
begin getmem(buf,1024);
repeat
zeromemory(buf,1024);
re:=recv(skt1,buf^,1024,0);
str:=strpas(buf);
memo1.lines.add(str);
showmessage('实际收到的字节数目:'+inttostr(re));
until re=0;
freemem(buf);
end;
fd_write://showmessage('write');
end;
end;
//procedure tform1.my1(var msg:tmessage);
//begin
//showmessage('write!');
//end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if wsastartup(makeword(2,0),wsadata)<>0 then
showmessage('初始化winsock2.2not ok!');
skt:=socket(af_inet,sock_stream,0);
if skt=invalid_socket then
showmessage('创建socket句柄not ok');
sa.sin_family:=af_inet;
sa.sin_port:=htons(7016);
sa.sin_addr.S_addr:=inet_addr('127.0.0.1');
if bind(skt,sa,sizeof(sa))=socket_error then
showmessage('ip和地址绑定not ok');
if listen(skt,2) = socket_error then
showmessage('监听not ok');
if wsaasyncselect(skt,form1.handle,async_event,fd_accept or fd_read or fd_write)=socket_error then
showmessage('异步化设置not ok');
end;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var buf:pchar;
str:string;
i:integer;
begin
if key=vk_return then
begin
getmem(buf,1024);
zeromemory(buf,1024);
str:=edit1.Text+#10;
strpcopy(buf,str);
//showmessage(buf);
showmessage('buf is:'+buf);
i:=send(skt,buf^,length(buf),0);
showmessage('message have sent:'+inttostr(i));
//showmessage('sucess');
freemem(buf);
end;
end;
end.
主要的错误是在检测到fd_accept网络事件的时候调用的acccept函数老是不能成功的
建立一个新的socket(返回结果老是invalid_socket),当然也就不可以利用这个socket
来传送编辑框中键入的信息了。最好大家能修改后给我一个原代码。shout@371.net!谢谢!
 
如果能给贴一个服务器端和客户端的完整源程序就更加好了.
注意,不要使用socket控件方法的,要完全使用WSA编程的.
 
我来回答你,下面是原代码的修改版.
unit Unit1;

interface

uses
Windows,winsock, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,shellapi;
const async_event=500+1;
//async_event1=502;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
Label1: TLabel;
Button2: TButton;
Edit2: TEdit;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
procedure Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
procedure my(var msg:tmsg);message async_event;
//procedure my1(var msg:tmessage);message async_event1;
public
{ Public declarations }
end;

var
Form1: TForm1;
wsadata:twsadata;
info:string;
bufsend,bufrecv:pchar;
skt,skt1:tsocket;
addr:tsockaddr;
re:integer;
sa,sa1:sockaddr_in;
implementation

{$R *.DFM}
procedure tform1.my(var msg:tmsg);
var flag:integer;
buf:pchar;
str:string;
// i:integer;
begin
//showmessage('lparam的值是:'+inttostr(msg.lparam));
//showmessage('wparam的数值是:'+inttostr(msg.wParam));
re:=sizeof(sa1);
//showmessage('accept');
//showmessage('用于监听信息的socket:'+inttostr(skt));
//showmessage(inttostr(msg.wParam));;
flag:=wsagetselectevent(msg.wParam);
case flag of
fd_accept:
begin
skt1:=accept(skt,@sa1,@re);
if skt1=invalid_socket then
//showmessage('用于传送信息的socket错误!');
//showmessage('用户传送信息的socket:'+inttostr(skt1));
end;
fd_read:
begin getmem(buf,1024);
repeat
zeromemory(buf,1024);
re:=recv(skt1,buf^,1024,0);
str:=strpas(buf);
if str<>'' then
memo1.lines.add(str);
//showmessage('实际收到的字节数目:'+inttostr(re));
until re=-1;
freemem(buf);
end;
fd_close:
begin
showmessage('远程的连接已经被中断!');
closesocket(skt1);
end;
fd_write://showmessage('write');
end;
end;
//procedure tform1.my1(var msg:tmessage);
//begin
//showmessage('write!');
//end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if wsastartup(makeword(2,0),wsadata)<>0 then
showmessage('初始化winsock2.2not ok!');
skt:=socket(af_inet,sock_stream,0);
if skt=invalid_socket then
showmessage('创建socket句柄not ok');
sa.sin_family:=af_inet;
sa.sin_port:=htons(7016);
while edit2.text='' do
begin
edit2.text:=inputbox('请输入本机的IP地址!','地址:','');
end;
sa.sin_addr.S_addr:=inet_addr(pchar(edit2.text));
if bind(skt,sa,sizeof(sa))=socket_error then
showmessage('ip和地址绑定not ok');
if listen(skt,2) = socket_error then
showmessage('监听not ok');
if wsaasyncselect(skt,form1.handle,async_event,fd_accept or fd_read or fd_write or fd_close)=socket_error then
showmessage('异步化设置not ok');
end;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var buf:pchar;
str:string;
i:integer;
begin
if key=vk_return then
begin
getmem(buf,1024);
zeromemory(buf,1024);
str:=edit1.Text+#10;
strpcopy(buf,str);
//showmessage(buf);
//showmessage('buf is:'+buf);
i:=send(skt1,buf^,length(buf),0);
//showmessage('message have sent:'+inttostr(i));
//showmessage('sucess');
freemem(buf);
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
sendmessage(form1.edit1.handle,wm_keydown,13,0);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
closesocket(skt);
wsacleanup;
end;

end.

 

Similar threads

后退
顶部