Socket编程的问题,请高手看看 ( 积分: 50 )

  • 主题发起人 主题发起人 hejian_2002
  • 开始时间 开始时间
H

hejian_2002

Unregistered / Unconfirmed
GUEST, unregistred user!
是这样的,一个server监听,4个client连上来,通讯包来了以后,放到一个等待处理
队列中,另外一个线程a一发现有数据,就处理,然后放到一个发送队列中,发送线程
b处理发送队列中数据,发回到相应的client(这个数据原来是哪个client来的,就发回
哪个去),每个通讯包都有自己的地方特征数据,不过只是在当天当次长连接通讯中
不变,所以必须在每个client连上来时要记住每个连接的标识。
问题是:在一个client连上来,serversocket就增加一个连接(connects[]数组增加一个),
我希望得到每一个client对应的connect的号码,放在一个数组中,这样在发送回去时,
只要看看数组中地方特征数据对应的connect的号码(比如3),就可以调用serversocket.socket.
connects[3].sendbuf(pkg,sizeof(Tpkg)),可是我怎么也得不到这个连接号码,

我希望大家有没有其他的解决方法,
 
是这样的,一个server监听,4个client连上来,通讯包来了以后,放到一个等待处理
队列中,另外一个线程a一发现有数据,就处理,然后放到一个发送队列中,发送线程
b处理发送队列中数据,发回到相应的client(这个数据原来是哪个client来的,就发回
哪个去),每个通讯包都有自己的地方特征数据,不过只是在当天当次长连接通讯中
不变,所以必须在每个client连上来时要记住每个连接的标识。
问题是:在一个client连上来,serversocket就增加一个连接(connects[]数组增加一个),
我希望得到每一个client对应的connect的号码,放在一个数组中,这样在发送回去时,
只要看看数组中地方特征数据对应的connect的号码(比如3),就可以调用serversocket.socket.
connects[3].sendbuf(pkg,sizeof(Tpkg)),可是我怎么也得不到这个连接号码,

我希望大家有没有其他的解决方法,
 
根据每个连接的句柄判断每个客户端的连接号码,然后发送出去。
 
赫赫,你可以自己订一下协议。比如可以在发送过来的数据中加上发送方的名称。然后在服务器端进行验证就好了。
 
你记住soket就行了啊
搞个用户和socket的对应表就可以了
 
自定义一个数组,把相关连接信息放进去就可以了
 
session_record=record
Used: boolean; { 会话记录是否可用 }
SS_Handle: integer; { 代理服务器套接字句柄 }
CSocket: TClientSocket; { 用于连接远程的套接字 }
Lookingup: boolean; { 是否正在查找服务器 }
LookupTime: integer; { 查找服务器时间 }
Request: boolean; { 是否有请求 }
request_str: string; { 请求数据块 }
client_connected: boolean; { 客户机联机标志 }
remote_connected: boolean; { 远程服务器连接标志 }
end;
//===========
猛料上有篇代理的例子,有类似的你看看
// 被代理端连接到代理服务器后 ,建立一个会话 ,并与套接字绑定…

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;

Socket: TCustomWinSocket);

var

i,j: integer;

begin

j:=-1;

for i:=1 to sessions do { 查找是否有空白项 }

if not session[i-1].Used and not session[i-1].CSocket.active then

begin

j:=i-1; { 有 ,分配它 }

session[j].Used:=true; { 置为在用 }

break;

end

else

if not session[i-1].Used and session[i-1].CSocket.active then

session[i-1].CSocket.active:=false;

if j=-1 then

begin { 无 ,新增一个 }

j:=sessions;

inc(sessions);

setlength(session,sessions);

session[j].Used:=true; { 置为在用 }

session[j].CSocket:=TClientSocket.Create(nil);

session[j].CSocket.OnConnect:=ClientSocket1Connect;

session[j].CSocket.OnDisconnect:=ClientSocket1Disconnect;

session[j].CSocket.OnError:=ClientSocket1Error;

session[j].CSocket.OnRead:=ClientSocket1Read;

session[j].CSocket.OnWrite:=ClientSocket1Write;

session[j].Lookingup:=false;

end;

session[j].SS_Handle:=socket.socketHandle; { 保存句柄 ,实现绑定 }

session[j].Request:=false; { 无请求 }

session[j].client_connected:=true; { 客户机已连接 }

session[j].remote_connected:=false; { 远程未连接 }

edit1.text:=inttostr(sessions);

end;


// 被代理端断开时…

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;

Socket: TCustomWinSocket);

var

i,j,k: integer;

begin

for i:=1 to sessions do

if (session[i-1].SS_Handle=socket.SocketHandle) and session[i-1].Used then

begin

session[i-1].client_connected:=false; { 客户机未连接 }

if session[i-1].remote_connected then

session[i-1].CSocket.active:=false { 假如远程尚连接 ,断开它 }

else

session[i-1].Used:=false; { 假如两者都断开 ,则置释放资源标志 }

break;

end;

j:=sessions;

k:=0;

for i:=1 to j do { 统计会话数组尾部有几个未用项 }

begin

if session[j-i].Used then

break;

inc(k);

end;

if k>0 then { 修正会话数组 ,释放尾部未用项 }

begin

sessions:=sessions-k;

setlength(session,sessions);

end;

edit1.text:=inttostr(sessions);

end;
 
建议你用Indy的端口映射控件,这样你连线程部分都不用管了。一切都是自动完成的。
 
记录socket的句柄啊,connecnt数一般在广播的时候比较好用
 
后退
顶部