Socket通讯(100分)

  • 主题发起人 主题发起人 yhnlzzg
  • 开始时间 开始时间
Y

yhnlzzg

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大侠,小弟有个小小小问题?不知哪位哥儿们知道怎么做?
这是一个有关SOCKET的问题(即移植问题),简单代码如下:
(我实在是不知错在哪里?请各位大哥指点指点!可不能用控件!!!)

unit socksc;

interface

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

type
TForm1 = class(TForm)
sockserver: TButton;
sockclient: TButton;
Memo1: TMemo;
Memo2: TMemo;
Edit1: TEdit;
Edit2: TEdit;
procedure sockserverClick(Sender: TObject);
procedure sockclientClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.sockserverClick(Sender: TObject);
var
fsock:Tsocket;
sockfd:Tsocket;
addr:Tsockaddr;
addrc:PSockAddr;
addrclen:PInteger;
rb,rl,rlog:integer;
str,str1:string;

begin
fsock:=socket(AF_INET,SOCK_STREAM,0);
memo1.Lines.Add('socket return: '+inttostr(fsock));
addr.sin_family:=AF_INET;
addr.sin_port:=2222;
addr.sin_addr.S_addr:=htonl(INADDR_ANY);
rb:=bind(fsock,addr,sizeof(addr));
memo1.Lines.Add('bind return: '+inttostr(rb));
rl:=listen(fsock,10);
memo1.Lines.Add('listen return: '+inttostr(rl));

addrclen^:=sizeof(addrc);

while (true) do
begin
sockfd:=accept(fsock,addrc,addrclen);
memo1.Lines.Add(inttostr(sockfd));
if sockfd>=0 then
begin

rlog:=recv(sockfd,str,sizeof(str),0);
if rlog<0 then continue;
memo1.Lines.Add(inttostr(rlog));
str1:=str+' ok!';
memo1.Lines.Add(inttostr(send(sockfd,str1,sizeof(str1),0)));
end
else
begin
memo1.Lines.Add('error!');
break;
end;
end;
closesocket(fsock);
end;

procedure TForm1.sockclientClick(Sender: TObject);
var
csock:Tsocket;
sockcd:Tsocket;
addrc:Tsockaddr;
rcon:integer;
strc,strc1:string;
begin
csock:=socket(AF_INET,SOCK_STREAM,0);
memo2.Lines.Add('socket return: '+inttostr(csock));
addrc.sin_family:=AF_INET;
addrc.sin_port:=2222;
addrc.sin_addr.S_addr :=inet_addr('192.168.1.23');
rcon:=connect(csock,addrc,sizeof(addrc));
memo2.Lines.Add('connect :'+inttostr(rcon));
strc:=edit1.text;
send(csock,strc,sizeof(strc),0);
recv(csock,strc1,sizeof(strc1),0);
edit2.text:=strc1;
closesocket(csock);
end;

end.
 
申明的这几个对象
fsock:Tsocket;
sockfd:Tsocket;
addr:Tsockaddr;
addrc:PSockAddr;
都没有使用Create方法动态创建啊,fsock := Tsocket.Create(self);
 
wd:wsadata; //接受window socket实现细节数据结构

wsastartup(2,wd); //初始化windows Sockets DLL
 
我问的问题都是早期版本的,并不涉及WINDOWS扩展函数?
 
但是在windows下,必须先初始化windows Sockets DLL,否则后面的一切都不运行
 
我想,初始化windows Sockets DLL(wsastartup())
是针对WINDOWS扩展函数而言的吧!对这些早期函数没有
什么影响!这段时间我又研究了一下,对上面的问题有所
改进,即加入线程,如此一来,若是SERVER和CLIENT都在
同一个程序(进程)中执行,相互之间可以通讯,但,要是
起两个程序(两个进程),相互之间可以连通,但CLIENT端
没有返回数据,我实在是没有解决的办法,改进的程序代码
如下:
unit socksc;

interface

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

type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
Edit1: TEdit;
Edit2: TEdit;
Button2: TButton;
Button3: TButton;
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}


function ThreadFunc():string;
var
fsock:Tsocket;
sockfd:Tsocket;
addr:Tsockaddr;
addrc:PSockAddr;
addrclen:Integer;
rb,rl,rlog,i:integer;
str,str1:string;
wd:wsadata;

begin
i:=0;
try
wsastartup(2,wd); //后加入的,但没有什么效果
fsock:=socket(AF_INET,SOCK_STREAM,0);
form1.memo1.Lines.Add('socket return: '+inttostr(fsock));
addr.sin_family:=AF_INET;
addr.sin_port:=2223;
addr.sin_addr.S_addr:=htonl(INADDR_ANY);
rb:=bind(fsock,addr,sizeof(addr));
form1.memo1.Lines.Add('bind return: '+inttostr(rb));
rl:=listen(fsock,5);
form1.memo1.Lines.Add('listen return: '+inttostr(rl));

addrclen:=sizeof(addrc);

while (true) do
begin
sockfd:=accept(fsock,addrc,PInteger(addrclen));
form1.memo1.Lines.Add('accept return: '+inttostr(sockfd));
if sockfd>=0 then
begin

rlog:=recv(sockfd,str,sizeof(str),0);

if rlog<0 then continue;
form1.memo1.Lines.Add('recv return: '+inttostr(rlog));
str1:=str+' ok!'+inttostr(i);
form1.memo1.Lines.Add('send return: '+inttostr(send(sockfd,str1,sizeof(str1),0)));
i:=i+1;

end
else
begin
form1.memo1.Lines.Add('error!');
break;
end;
end;
except
closesocket(fsock);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
hThread:THandle;
ThreadID:DWord;
begin
hthread:=createThread(nil,
0,
@ThreadFunc,
nil,
0,
ThreadID);
if hthread=0 then
messageBox(Handle,'No Thread',nil,MB_OK);

end;

function ThreadFunc1():string;
var
csock:Tsocket;
sockcd:Tsocket;
addrc:Tsockaddr;
rcon:integer;
strc,strc1:string;
wd:wsadata;

begin
wsastartup(2,wd);
csock:=socket(AF_INET,SOCK_STREAM,0);
form1.memo2.Lines.Add('socket return: '+inttostr(csock));
addrc.sin_family:=AF_INET;
addrc.sin_port:=2223;
addrc.sin_addr.S_addr :=inet_addr('192.168.1.23');
rcon:=connect(csock,addrc,sizeof(addrc));
form1.memo2.Lines.Add('connect :'+inttostr(rcon));
strc:=form1.edit1.text;
send(csock,strc,sizeof(strc),0);

sleep(2000);

recv(csock,strc1,sizeof(strc1),0);

form1.edit2.text:=strc1;
closesocket(csock);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
hThread:THandle;
ThreadID:DWord;
begin
hthread:=createThread(nil,
0,
@ThreadFunc1,
nil,
0,
ThreadID);
if hthread=0 then
messageBox(Handle,'No Thread',nil,MB_OK);

end;

end.

hua8hua这么长时间才回答,请你原谅,我也非常感谢你的答复!
但我仍然没有解决,你可以将此代码编译以下,研究研究,多谢!多谢!

 
可能和你的这几个变量的类型有关:
strc,strc1:string;
//////下面你试一试
function ThreadFunc():string;
var
fsock:Tsocket;
sockfd:Tsocket;
addr:Tsockaddr;
addrc:PSockAddr;
addrclen:Integer;
str:string;
rb,rl,rlog,i:integer;
wd:wsadata;
getbuf,putbuf:array[0..9]of char;
begin
i:=0;
wsastartup(2,wd); //后加入的,但没有什么效果
fsock:=socket(AF_INET,SOCK_STREAM,0);
try
if fsock>0
then form1.memo1.Lines.Add('服务器建立成功Socket='+inttostr(fsock))
else form1.memo1.Lines.Add('服务器建立失败');
addr.sin_family:=AF_INET;
addr.sin_port:=2223;
addr.sin_addr.S_addr:=htonl(INADDR_ANY);
rb:=bind(fsock,addr,sizeof(addr));
if rb=0
then form1.memo1.Lines.Add('服务器绑定成功')
else form1.memo1.Lines.Add('服务器绑定失败');
rl:=listen(fsock,5);
if rl=0
then form1.memo1.Lines.Add('服务器listen成功')
else form1.memo1.Lines.Add('服务器listen失败');
addrclen:=sizeof(addrc);
while (true) do
begin
//这句阻塞到客户端连接
sockfd:=accept(fsock,addrc,PInteger(addrclen));
if sockfd>0
then form1.memo1.Lines.Add('服务器接受Socket='+inttostr(sockfd)+'客户端成功')
else form1.memo1.Lines.Add('服务器接受Socket='+inttostr(sockfd)+'客户端失败');
if sockfd>=0
then begin
rlog:=recv(sockfd,getbuf,10,0);
if rlog<0 then continue;
form1.memo1.Lines.Add('接受长度='+inttostr(rlog));
form1.memo1.Lines.Add('接受数据='+trim(getbuf));
str:='987654321'+inttostr(i);
move(str[1],putbuf,10);
rlog:=send(sockfd,putbuf,10,0);
form1.memo1.Lines.Add('发送长度='+inttostr(rlog));
form1.memo1.Lines.Add('发送数据='+trim(putbuf));
form1.Memo1.Lines.Add('====================================');
i:=i+1;
end
else begin
form1.memo1.Lines.Add('error!');
break;
end;
end;
except
closesocket(fsock);
end;
end;

function ThreadFunc1():string;
var
csock:Tsocket;
addrc:Tsockaddr;
rcon:integer;
strc:string;
wd:wsadata;
getbuf,putbuf:array[0..9] of char;
begin
wsastartup(2,wd);
csock:=socket(AF_INET,SOCK_STREAM,0);
form1.memo2.Lines.Add('客户端建立成功Socket='+inttostr(csock));
addrc.sin_family:=AF_INET;
addrc.sin_port:=2223;
addrc.sin_addr.S_addr :=inet_addr('128.1.121.121');
rcon:=connect(csock,addrc,sizeof(addrc));
if rcon=0
then form1.memo2.Lines.Add('客户端连接128.1.121.121服务器成功')
else form1.memo2.Lines.Add('客户端连接128.1.121.121服务器失败');
strc:='1234567890';
move(strc[1],putbuf[0],10);
//发送
rcon:=send(csock,putbuf,10,0);
form1.Memo2.Lines.Add('发送长度:'+inttostr(rcon));
form1.Memo2.Lines.Add('发送数据:'+trim(putbuf));
//接受
rcon:=recv(csock,getbuf,10,0);
form1.Memo2.Lines.Add('接受长度:'+inttostr(rcon));
form1.Memo2.Lines.Add('接受数据:'+trim(getbuf));
form1.Memo2.Lines.Add('====================================');
closesocket(csock);
wsacleanup;
end;
 
才上网,不好意思,我非常谢谢你邦我解决了这个难题!多谢多谢!
如果你感兴趣的话,还有一个问题:这两者之间为什么一次只能通讯35次?
另外,怎样把CLIENT端嵌在ASP当中?
 

Similar threads

I
回复
0
查看
1K
import
I
I
回复
0
查看
600
import
I
I
回复
0
查看
674
import
I
后退
顶部