当前位置:主页>仓库管理软件> 列表

winsock多客户端问题 找电脑管理软件

销售管理软件版1楼: unit Unit1;

interface

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

const
WM_SOCK = WM_USER + 1; //自定义windows消息
TCP_PORT = 7010; //设定TCP祯听端口号

type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
HasConnected, IsServer: boolean;
CliSocket, SvrSocket: integer;
SvrAddrIn, CliAddrIn:TSockAddrIn;
procedure InitSocket;
procedure SendData(Content: string);
procedure ReadData(var Message: TMessage); message WM_SOCK;
procedure SockConnect;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.InitSocket;
var
wsadata: TWsadata;
err{, optval}: integer;
begin


WSAStartup($0101,WSAData);

CliSocket := socket(AF_INET, SOCK_STREAM,IPPROTO_IP);
SvrSocket := socket(AF_INET, SOCK_STREAM,IPPROTO_IP);

if (CliSocket = INVALID_SOCKET)or(SvrSocket = INVALID_SOCKET) then
begin
ShowMessage(inttostr(WSAGetLastError())+'' Socket创建失败'');
CloseSocket(CliSocket);
exit;
end;

SvrAddrIn.sin_addr.s_addr:= INADDR_ANY;
SvrAddrIn.sin_family := AF_INET;
SvrAddrIn.sin_port :=htons(TCP_PORT);
Bind(SvrSocket, SvrAddrIn, sizeof(SvrAddrIn));

err := Listen(SvrSocket,5);
if err<>0 then ShowMessage(''祯听错误!'');

{optval := 1;
if SetSockopt(SvrSocket,SOL_SOCKET,SO_REUSEADDR,pchar(@optval),sizeof(optval)) = SOCKET_ERROR then
begin
showmessage(''SO_REUSEADDR set error.'');
end; }

//绑定消息映射
WSAAsyncSelect(SvrSocket, Handle , WM_SOCK, FD_READ or FD_ACCEPT or FD_CONNECT or FD_WRITE or FD_CLOSE);
WSAAsyncSelect(CliSocket, Handle , WM_SOCK, FD_READ or FD_ACCEPT or FD_CONNECT or FD_WRITE or FD_CLOSE);

end;

procedure TForm1.SockConnect;
var
err: integer;
begin

CliAddrIn.sin_addr.s_addr:=inet_addr(PChar(Edit1.Text));
CliAddrIn.sin_family := AF_INET;
CliAddrIn.sin_port :=htons(TCP_PORT);
repeat
err:=connect(CliSocket,CliAddrIn, SizeOf(CliAddrIn));
if err = -1 then
begin
//ShowMessage(''连接错误.'');
//ListBox1.Items.Add(''连接错误.'');
HasConnected := false;
break;
end
else
begin
HasConnected := true;
IsServer := false;
end;
until err=0;

end;

procedure TForm1.SendData(Content: string);
begin
Send(CliSocket,Content[1],length(Content),0);
end;

procedure TForm1.ReadData(var Message: TMessage);
var
Event: word;
Buf:array[0..1023] of char;
AddrLen, DataLen: integer;
begin
//
AddrLen := sizeof(SvrAddrIn);
Event := WSAGetSelectEvent(Message.LParam);

case Event of
FD_CONNECT:
begin
ListBox1.Items.Add(''connect'');
HasConnected := true;
//do nothing?
end;
FD_ACCEPT:
begin
IsServer := true;
HasConnected := true;
ListBox1.Items.Add(''accept'');
//CloseSocket(CliSocket);
CliSocket := Accept(SvrSocket,@SvrAddrIn,@AddrLen);
end;
FD_READ:
begin
DataLen := Recv(CliSocket,Buf,1024,0);
buf[DataLen] := #0;
ListBox1.Items.Add(Buf);
end;
FD_WRITE:
begin
ListBox1.Items.Add(''write'');
end;
FD_OOB:
begin
ListBox1.Items.Add(''FD_OOB'');
end;
FD_CLOSE:
begin
HasConnected := false;
ListBox1.Items.Add(''close'');
end;
end; //end of case
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
//202.104.32.230
if (not IsServer)and(not HasConnected) then SockConnect;
SendData(''你好吗!'');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSocket(SvrSocket);
CloseSocket(CliSocket);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
HasConnected := false;
IsServer := false;
InitSocket;
end;

end.
小弟最近正在做一个基于GPRS手机摸块通信程序。一个服务端,多个客户端,每个客户端都有一个带TCP/IP协议的手机摸块,服务端在控制中心并接入宽带。每开启一个客户端后,服务端都能接收到客户的信息。问题是:在如何在服务端向各个客户端发送信息。这是否需要做多线程,请各位高手不吝赐教。谢谢!

2楼: 咋没有人来拿分啊 如管家婆进销存

3楼: 这么长的啊,呵呵,不懂。
procedure SendTextToClient(Const ASocket: TServerSocket; Const AText: String);
var
j: Integer;
begin
for j:=0 to ASocket.Socket.ActiveConnections-1 do
try
ASocket.Socket.Connections[j].SendText(AText);
except
end;
end;

我用的是ServerSocket/ClientSocket,不知是否有所启发。

4楼: 学习

5楼: 关注!客户端的数量凭什么来确定,它的上限又是多少呢?有什么软件可以来检测?

6楼: 如果服务端和客户端的通信量不大的话,而且并发在一百之内的话,用你上面的异步SELECT模型就可以了。
如果是长时间的连接和较大的通信量,还是走多线程的服务为好。

销售管理软件版7楼: 楼主,你有没有异步这方面的资料啊!


能不能发给我一份!?kp1150@163.com

8楼: 可以把客户端的信息包括SOCKET放入LIST中

9楼: 建立监听线程,接收到连接后,读取客户端信息,一并和accept生成的socket作为对象存入
list

10楼: 直接使用API来做,不难!
只要是在客户端连接上来的时候将套接字记录下来,然后发送的时候使用这个套接字将数据发送出去就可以了!
如果有上千的客户端连接建议使用IOCP方式!

11楼: 用tcpclient控件不就行了!

12楼: 用IPCP在www.tomore.com上有例子,看去吧 如电脑管理软件

13楼: http://www.delphibbs.com/keylife/images/u196832/reverse0617.rar