delphi serversocket与clientsocket通讯的问题?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi serversocket与clientsocket通讯的问题?相关的知识,希望对你有一定的参考价值。

2个或以上clientsocket连接serversocket,serversocket如何区分不同的客户端?用ListBox显示连接的客户端,如何给不同的客户端发信息?
注意:是 delphi
1楼的,你的代码没有我要的功能。。。我的要求是,选择ListBox中显示连接的N个客户端中任意一个,通过button,按钮,发送信息。。。这个如何实现?
我现在是:for i:=0 to sessions do
begin //取得匹配的客户端
if session[i].CName = trim(edtServer.Text) then
begin
//.......
end
end;
我的程序有个问题,就是,登陆N个客户端,客户端给服务器发信息没问题,但是服务端只能给N-1个客户端发信息

serversocket源码:
const
CMax=10; //客户端最大连接数,具体需求,自己设置
type
client_record=record
CHandle: integer; //客户端套接字句柄
CSocket:TCustomWinSocket; //客户端套接字
CName:string; //客户端计算机名称
CAddress:string; //客户端计算机IP地址
CUsed: boolean; //客户端联机标志
end;
//////////////
session: array[0..CMax] of client_record; //客户端连接数组
Sessions: integer;

//打开套接字连接,并使套接字进入监听状态
procedure TfrmServerMain.tbConnectClick(Sender: TObject);
begin
serversocket.Port:=9999;//监听端口
ServerSocket.Open ;
end;
//关闭套接字连接,不再监听客户端的请求
procedure TfrmServerMain.tbDisconnectedClick(Sender: TObject);
begin
ServerSocket.Close;
StatusBar.Panels[0].Text :='服务器套接字连接已经关闭,无法接受客户端的连接请求.';
end;
//从客户端读取信息
procedure TfrmServerMain.ServerSocketClientRead(Sender: TObject;Socket: TCustomWinSocket);

var
i:integer;
begin
//将从客户端读取的信息添加到Memo1中
Memo1.Lines.Add(Socket.ReceiveText);
for i:=0 to sessions do
begin
//取得匹配的客户端
if session[i].CHandle = Socket.SocketHandle then
begin
session[i].CSocket.SendText('回复客户端'+session[i].CAddress+' ==> '+Edit1.Text);
end;
end;
end;
//服务器端套接字进入监听状态,以便监听客户端的连接
procedure TfrmServerMain.ServerSocketListen(Sender: TObject;Socket: TCustomWinSocket);
begin
StatusBar.Panels[0].Text :='等待客户端连接...';
end;
//当客户端连接到服务器端以后
procedure TfrmServerMain.ServerSocketClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
i,j:integer;begin
begin
j:=-1;
for i:=0 to sessions do
begin
//在原有的客户端连接数组中有中断的客户端连接
if not session[i].CUsed then
begin
session[i].CHandle := Socket.SocketHandle ;//客户端套接字句柄
session[i].CSocket := Socket; //客户端套接字
session[i].CName := Socket.RemoteHost ; //客户端计算机名称
session[i].CAddress := Socket.RemoteAddress ;//客户端计算机IP
session[i].CUsed := True; //连接数组当前位置已经占用
Break;
end;
j:=i;
end;
if j=sessions then
begin
inc(sessions);
session[j].CHandle := Socket.SocketHandle ;
session[j].CSocket := Socket;
session[j].CName := Socket.RemoteHost ;
session[j].CAddress := Socket.RemoteAddress ;
session[j].CUsed := True;
end;
StatusBar.Panels[0].Text := '客户端 '+Socket.RemoteHost + ' 已经连接';
end;
//当客户端断开连接时
procedure TfrmServerMain.ServerSocketClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
var
i:integer;
begin
for i:=0 to sessions do
begin
if session[i].CHandle =Socket.SocketHandle then
begin
session[i].CHandle :=0;
session[i].CUsed := False;
Break;
end;
end;
StatusBar.Panels[0].Text :='客户端 '+Socket.RemoteHost + ' 已经断开';
end;
//关闭窗口
procedure TfrmServerMain.tbCloseClick(Sender: TObject);
begin
Close;
end;
procedure TfrmServerMain.FormCreate(Sender: TObject);
begin
sessions := 0;
end;
procedure TfrmServerMain.FormClose(Sender: TObject;var Action: TCloseAction);
begin
ServerSocket.Close ;
end;
//当客户端正在与服务器端连接时
procedure TfrmServerMain.ServerSocketGetSocket(Sender: TObject;
Socket: Integer; var ClientSocket: TServerClientWinSocket);
begin
StatusBar.Panels[0].Text :='客户端正在连接...';
end;
//客户端发生错误
procedure TfrmServerMain.ServerSocketClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
StatusBar.Panels[0].Text :='客户端'+Socket.RemoteHost +'发生错误!';
ErrorCode := 0;
end;
====================================================================
客户端源码:
procedure TfrmClientMain.tbConnectedClick(Sender: TObject);
begin
ClientSocket.Host:=‘127.0.0.1’;//连接IP
ClientSocket.Port:=9999; //连接端口
ClientSocket.Open ;
end;
//关闭套接字连接
procedure TfrmClientMain.tbDisconnectedClick(Sender: TObject);
begin
ClientSocket.Close;
end;
//接受服务器端的回复
procedure TfrmClientMain.ClientSocketRead(Sender: TObject;Socket: TCustomWinSocket);
begin
Memo1.Lines.Add(Socket.ReceiveText);
end;
//发送信息到服务器端
procedure TfrmClientMain.tbSendClick(Sender: TObject);
begin
ClientSocket.Socket.SendText(Edit1.Text);
end;
procedure TfrmClientMain.tbCloseClick(Sender: TObject);
begin
Close;
end;
//设置要连接的服务器端地址
procedure TfrmClientMain.FormShow(Sender: TObject);
begin
ClientSocket.Host := SocketHost;
end;
//已经连接到服务器端
procedure TfrmClientMain.ClientSocketConnect(Sender: TObject;Socket: TCustomWinSocket);
begin
tbSend.Enabled := True;
tbDisconnected.Enabled :=True;
btnSend.Enabled := True;
StatusBar.Panels[0].Text := '已经连接到 '+ Socket.RemoteHost ;
end;
//正在连接到服务器端
procedure TfrmClientMain.ClientSocket1Connecting(Sender: TObject;Socket: TCustomWinSocket);
begin
StatusBar.Panels[0].Text := '正在连接到服务器... ' ;
end;
//当断开与服务器端的连接时发生
procedure TfrmClientMain.ClientSocketDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
tbSend.Enabled := False;
btnSend.Enabled := False
tbDisconnected.Enabled := False;
StatusBar.Panels[0].Text := '已经断开与 '+ Socket.RemoteHost +' 的连接';
end;
procedure TfrmClientMain.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
ClientSocket.Close ;
end;
//当与服务器端的连接发生错误时
procedure TfrmClientMain.ClientSocketError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;var ErrorCode: Integer);
begin
StatusBar.Panels[0].Text := '与服务器端的连接发生错误';
ErrorCode := 0;
end;
end.
参考技术A clientsocket和serversocket都不能用于实例
它们通常只作为socket函数的参数出现
在delphi中,使用socket必须指协议类型
如tcpserver,tcpclient,udpserver,udpclient等等
参考技术B 1.简单服务器
//#include <winsock2.h>
//#pragma comment(lib,"WS2_32.lib")
WSADATA wsd;
static UINT port=%%1;
UINT Listen(LPVOID pParam)

SOCKET sServer,sClient;
char buf[1024];
int retVal;
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)

return -1;//失败

sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET==sServer)

WSACleanup();
return -1;//创建套接字失败

SOCKADDR_IN addrServ;
addrServ.sin_family=AF_INET;
addrServ.sin_port=htons((short)pParam);
addrServ.sin_addr.s_addr=INADDR_ANY;
retVal=bind(sServer,(LPSOCKADDR)&addrServ,sizeof(SOCKADDR_IN));
if(SOCKET_ERROR==retVal)

closesocket(sServer);
WSACleanup();
return -1;//绑定套接字失败

retVal=listen(sServer,1);
if(SOCKET_ERROR==retVal)

closesocket(sServer);
WSACleanup();
return -1;//开始监听失败

sockaddr_in addrClient;
int addrClientlen=sizeof(addrClient);
sClient=accept(sServer,(sockaddr FAR*)&addrClient,&addrClientlen);
if(INVALID_SOCKET==sClient)

closesocket(sServer);
WSACleanup();
return -1;//开始接受客户端连接失败

ZeroMemory(buf,sizeof(buf));
retVal=recv(sClient,buf,sizeof(buf),0);
if(SOCKET_ERROR==retVal)

closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;//接收数据失败

CString %%2(buf);
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return 0;

CWinThread *pThread=AfxBeginThread(Listen,&port);

2.简单客户端
//#include <winsock2.h>
//#pragma comment(lib,"WS2_32.lib")
WSADATA wsd;
SOCKET sHost;
SOCKADDR_IN servAddr;
char buf[1024];
int retVal;
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)

return -1;//失败

sHost=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET==sHost)

WSACleanup();
return -1;//创建套接字失败

servAddr.sin_family=AF_INET;
servAddr.sin_addr.s_addr=inet_addr(%%3);
servAddr.sin_port=htons((short)%%2);
int nServAddlen=sizeof(servAddr);
retVal=connect(sHost,(LPSOCKADDR)&servAddr,sizeof(servAddr));
if(SOCKET_ERROR==retVal)
closesocket(sHost);
WSACleanup();
return -1;//连接服务器失败

ZeroMemory(buf,sizeof(buf));
strcpy(buf,%%3);
retVal=send(sHost,buf,sizeof(buf),0);
if(SOCKET_ERROR==retVal)

closesocket(sHost);
WSACleanup();
return -1;//向服务器发送数据失败

closesocket(sHost);
WSACleanup();

3.获得本机IP
//#include <winsock2.h>
//#pragma comment(lib,"WS2_32.lib")
WSADATA wsd;
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)

return -1;//失败

char szHostname[100],szHostaddress[200];
if(gethostname(szHostname,sizeof(szHostname))!=SOCKET_ERROR)

HOSTENT *pHostEnt=gethostbyname(szHostname);
if(pHostEnt!=NULL)
sprintf(szHostaddress,"%d.%d.%d.%d",
( pHostEnt->h_addr_list[0][0]&0x00ff ),
( pHostEnt->h_addr_list[0][1]&0x00ff ),
( pHostEnt->h_addr_list[0][2]&0x00ff ),
( pHostEnt->h_addr_list[0][3]&0x00ff ));


else
return;
CString %%1(szHostaddress);

4.端对端通信
//#include <winsock2.h>
//#pragma comment(lib,"WS2_32.lib")
WSADATA wsd;
SOCKET s;
char buf[1024];
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)

return -1;//失败

s=socket(AF_INET,SOCK_DGRAM,0);
if(s==INVALID_SOCKET)

WSACleanup();
return -1;//创建套接字失败

SOCKADDR_IN servAddr;
servAddr.sin_family=AF_INET;
servAddr.sin_addr.s_addr=inet_addr(%%1);
servAddr.sin_port=htons(INADDR_ANY);
if(bind(s,(SOCKADDR*)&servAddr,sizeof(SOCKADDR_IN))==SOCKET_ERROR)

closesocket(s);
WSACleanup();
return -1;//绑定套接字失败

int nServAddrlen=sizeof(servAddr);
ZeroMemory(buf,sizeof(buf));
if(recvfrom(s,buf,sizeof(buf),0,(SOCKADDR*)&servAddr,&nServAddrlen)==SOCKET_ERROR)

closesocket(s);
WSACleanup();
return -1;//接收数据失败

CString %%2(buf);
ZeroMemory(buf,sizeof(buf));
strcpy(buf,%%3);
SOCKADDR_IN clientAddr;
clientAddr.sin_family=AF_INET;
clientAddr.sin_addr.s_addr=inet_addr(%%4);
clientAddr.sin_port=htons((short)%%5);
int nClientlen=sizeof(clientAddr);
if(sendto(s,buf,sizeof(buf),0,(SOCKADDR*)&clientAddr,nClientlen)==SOCKET_ERROR)

closesocket(s);
WSACleanup();
return -1;//向服务器发送数据失败

closesocket(s);
WSACleanup();

5.点对点通信
//#include <winsock2.h>
//#pragma comment(lib,"WS2_32.lib")
WSADATA wsd;
SOCKADDR_IN addrServ,addrServ2;
SOCKET sServer,sClient,sHost;
int retVal;
sockaddr_in addrClient;
char buf[1024];
static UINT port=%%2;
BOOL listenerRun=TRUE;
UINT Listen(LPVOID pParam)

addrServ.sin_family=AF_INET;
addrServ.sin_port=htons((UINT)pParam);
addrServ.sin_addr.s_addr=INADDR_ANY;
retVal=bind(sServer,(LPSOCKADDR)&addrServ,sizeof(SOCKADDR_IN));
if(SOCKET_ERROR==retVal)

closesocket(sServer);
WSACleanup();
return -1;//绑定套接字失败

retVal=listen(sServer,1);
if(SOCKET_ERROR==retVal)

closesocket(sServer);
WSACleanup();
return -1;//开始监听失败

int addrClientlen=sizeof(addrClient);
sClient=accept(sServer,(sockaddr FAR*)&addrClient,&addClientlen);
if(INVALID_SOCKET==sClient)

closesocket(sServer);
WSACleanup();
return -1;//接收客户端请求失败

while(listenerRun)

ZeroMemory(buf,sizeof(buf));
retVal=recv(sClient,buf,sizeof(buf));
if(SOCKET_ERROR==retVal)

closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;//接收客户端数据失败

CString %%4(buf);


if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)

return -1;//失败

sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET==sServer)

WSACleanup();
return -1;//创建套接字失败

CWinThread *pThread=AfxBeginThread(Listen,&port);
sHost=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET==sHost)

WSACleanup();
return -1;//创建套接字失败

servAddr2.sin_family=AF_INET;
servAddr2.sin_addr.s_addr=inet_addr(%%1);
servAddr.sin_port=htons((short)%%3);
int nServerAddrlen=sizeof(servAddr2);
retVal=connect(sHost,(LPSOCKADDR)&servAddr2,sizeof(servAddr2));
if(SOCKET_ERROR==retVal)

closesocket(sHost);
WSACleanup();
return -1;//连接失败

zeroMemory(buf,sizeof(buf));
strcpy(buf,%%5);
retVal=send(sHost,buf,sizeof(buf),0);
if(SOCKET_ERROR==retVal)

closesocket(sHost);
WSACleanup();
return -1;//向发送数据失败

listenerRun=FALSE;
DWORD dwExitCode;
::GetExitCodeThread(pThread->m_hThread,&dwExitCode);
pThread=null;
closesocket(sServer);
closesocket(sClient);
closesocket(sHost);
WSACleanup();
参考技术C for i:=low(sessions) to High(sessions) do
begin

end;

以上是关于delphi serversocket与clientsocket通讯的问题?的主要内容,如果未能解决你的问题,请参考以下文章

delphi XE8 TDSServer服务端怎样接收客户端消息

Delphi的Socket编程步骤(repulish)

java通过ServerSocket与Socket实现通信

java通过ServerSocket与Socket实现通信

ServerSocket与Socket的区别

Java - 无法与 ServerSocket 连接