TCP轉發伺服器的例子
這幾種機器用事件模型應該夠用了。
下面是一個TCP轉發伺服器的例子,他的作用是有一些客戶端連到伺服器後,任何一個客戶端發給伺服器的資料都被伺服器原封不動的轉發到所有客戶端,類似於多人聊天的概念。
program EventSelectServer;
{$APPTYPE CONSOLE}
uses
SysUtils, WinSock2;
const
Port = 5150;
MaxConnection = 63;
BufSize = 1024;
var
wsaData: TWSAData;
Connection: array [0..MaxConnection] of TSocket;
Events: array [0..MaxConnection] of WSAEvent;
ConnectionNum: Integer;
Index: Integer;
i, j: Integer;
NetworkEvent: TWSANetworkEvents;
ServerAddr: TSockAddrIn;
ClientAddr: TSockAddrIn;
ClientAddrLen: Integer;
Buf: string;
Ret: Integer;
begin
Ret:=WSAStartup($202, wsaData);
if Ret<>0 then
begin
WriteLn('WSAStartup failed with error ', Ret);
ReadLn;
Exit
end;
ConnectionNum:=1;
Connection[0]:=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if Connection[0]=INVALID_SOCKET then
begin
WriteLn('socket failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
ServerAddr.sin_family:=AF_INET;
ServerAddr.sin_port:=htons(Port);
ServerAddr.sin_addr.S_addr:=htonl(INADDR_ANY);
if bind(Connection[0], @ServerAddr, SizeOf(ServerAddr))=SOCKET_ERROR then
begin
WriteLn('bind failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
Events[0]:=WSACreateEvent;
if Events[0]=WSA_INVALID_EVENT then
begin
WriteLn('WSACreateEvent failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
if WSAEventSelect(Connection[0], Events[0], FD_ACCEPT)=SOCKET_ERROR then
begin
WriteLn('WSAEventSelect failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
if listen(Connection[0], 5)=SOCKET_ERROR then
begin
WriteLn('listen failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
while True do
begin
Ret:=WSAWaitForMultipleEvents(ConnectionNum, @Events[0], False, WSA_INFINITE, False);
Index:=Ret-WSA_WAIT_EVENT_0;
for i:=Index to ConnectionNum-1 do
begin
Ret:=WSAWaitForMultipleEvents(1, @Events, True, 0, False);
if (Ret=WSA_WAIT_FAILED) or (Ret=WSA_WAIT_TIMEOUT) then
Continue;
if WSAEnumNetworkEvents(Connection, Events, @NetworkEvent)=SOCKET_ERROR then
Continue;
if (NetworkEvent.lNetworkEvents and FD_ACCEPT)<>0 then
begin
if NetworkEvent.iErrorCode[FD_ACCEPT_BIT]<>0 then
begin
WriteLn('FD_ACCEPT failed with error ', NetworkEvent.iErrorCode[FD_ACCEPT_BIT]);
Continue
end;
if ConnectionNum<=MaxConnection then
begin
ClientAddrLen:=SizeOf(ClientAddr);
Connection[ConnectionNum]:=accept(Connection, ClientAddr, ClientAddrLen);
if Connection[ConnectionNum]=INVALID_SOCKET then
begin
WriteLn('accept failed with error ', WSAGetLastError);
Continue
end;
Events[ConnectionNum]:=WSACreateEvent;
if Events[ConnectionNum]=WSA_INVALID_EVENT then
begin
WriteLn('WSACreateEvent failed with error ', WSAGetLastError);
if closesocket(Connection[ConnectionNum])=SOCKET_ERROR then
WriteLn('closesocket failed with error ', WSAGetLastError);
Continue
end;
if WSAEventSelect(Connection[ConnectionNum], Events[ConnectionNum], FD_READ or FD_CLOSE)=SOCKET_ERROR then
begin
WriteLn('WSAEventSelect failed with error ', WSAGetLastError);
if closesocket(Connection[ConnectionNum])=SOCKET_ERROR then
WriteLn('closesocket failed with error ', WSAGetLastError);
if not WSACloseEvent(Events[ConnectionNum]) then
WriteLn('WSACloseEvent failed with error ', WSAGetLastError);
Continue
end;
WriteLn('accetp ', inet_ntoa(ClientAddr.sin_addr), ':', ntohs(ClientAddr.sin_port));
Inc(ConnectionNum)
end
end;
if (NetworkEvent.lNetworkEvents and FD_READ)<>0 then
begin
if NetworkEvent.iErrorCode[FD_READ_BIT]<>0 then
begin
WriteLn('FD_READ failed with error ', NetworkEvent.iErrorCode[FD_READ_BIT]);
Continue
end;
SetLength(Buf, BufSize);
Ret:=recv(Connection, Buf[1], BufSize, 0);
if Ret=SOCKET_ERROR then
begin
WriteLn('recv failed with error ', WSAGetLastError);
Continue
end;
SetLength(Buf, Ret);
ClientAddrLen:=SizeOf(ClientAddr);
if getpeername(Connection, ClientAddr, ClientAddrLen)=SOCKET_ERROR then
begin
WriteLn('getpeername failed with error ', WSAGetLastError);
Continue
end;
Buf:='來自'+inet_ntoa(ClientAddr.sin_addr)+':'+IntToStr(ntohs(ClientAddr.sin_port))+' '+Buf;
Buf:=TimeToStr(Time)+' '+Buf;
for j:=1 to ConnectionNum do
if send(Connection[j], Buf[1], Length(Buf), 0)=SOCKET_ERROR then
begin
WriteLn('send failed with error ', WSAGetLastError);
Continue
end;
WriteLn(Buf)
end;
if (NetworkEvent.lNetworkEvents and FD_CLOSE)<>0 then
begin
if NetworkEvent.iErrorCode[FD_CLOSE_BIT]<>0 then
begin
WriteLn('FD_CLOSE failed with error ', NetworkEvent.iErrorCode[FD_CLOSE_BIT]);
Continue
end;
ClientAddrLen:=SizeOf(ClientAddr);
if getpeername(Connection, ClientAddr, ClientAddrLen)=SOCKET_ERROR then
begin
WriteLn('getpeername failed with error ', WSAGetLastError);
Continue
end;
Buf:='closesocket '+inet_ntoa(ClientAddr.sin_addr)+':'+IntToStr(ntohs(ClientAddr.sin_port));
WriteLn(Buf);
if closesocket(Connection)=SOCKET_ERROR then
WriteLn('closesocket failed with error ', WSAGetLastError);
if not WSACloseEvent(Events) then
WriteLn('WSACloseEvent failed with error ', WSAGetLastError);
if ConnectionNum>1 then
begin
Connection:=Connection[ConnectionNum-1];
Events:=Events[ConnectionNum-1];
Dec(ConnectionNum)
end
end
end
end;
for i:=0 to ConnectionNum do
if closesocket(Connection)=SOCKET_ERROR then
begin
WriteLn('closesocket failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
if WSACleanup=SOCKET_ERROR then
begin
WriteLn('WSCleanup failed with error ', WSAGetLastError);
ReadLn;
Exit
end
end.
下面是一個TCP轉發伺服器的例子,他的作用是有一些客戶端連到伺服器後,任何一個客戶端發給伺服器的資料都被伺服器原封不動的轉發到所有客戶端,類似於多人聊天的概念。
program EventSelectServer;
{$APPTYPE CONSOLE}
uses
SysUtils, WinSock2;
const
Port = 5150;
MaxConnection = 63;
BufSize = 1024;
var
wsaData: TWSAData;
Connection: array [0..MaxConnection] of TSocket;
Events: array [0..MaxConnection] of WSAEvent;
ConnectionNum: Integer;
Index: Integer;
i, j: Integer;
NetworkEvent: TWSANetworkEvents;
ServerAddr: TSockAddrIn;
ClientAddr: TSockAddrIn;
ClientAddrLen: Integer;
Buf: string;
Ret: Integer;
begin
Ret:=WSAStartup($202, wsaData);
if Ret<>0 then
begin
WriteLn('WSAStartup failed with error ', Ret);
ReadLn;
Exit
end;
ConnectionNum:=1;
Connection[0]:=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if Connection[0]=INVALID_SOCKET then
begin
WriteLn('socket failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
ServerAddr.sin_family:=AF_INET;
ServerAddr.sin_port:=htons(Port);
ServerAddr.sin_addr.S_addr:=htonl(INADDR_ANY);
if bind(Connection[0], @ServerAddr, SizeOf(ServerAddr))=SOCKET_ERROR then
begin
WriteLn('bind failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
Events[0]:=WSACreateEvent;
if Events[0]=WSA_INVALID_EVENT then
begin
WriteLn('WSACreateEvent failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
if WSAEventSelect(Connection[0], Events[0], FD_ACCEPT)=SOCKET_ERROR then
begin
WriteLn('WSAEventSelect failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
if listen(Connection[0], 5)=SOCKET_ERROR then
begin
WriteLn('listen failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
while True do
begin
Ret:=WSAWaitForMultipleEvents(ConnectionNum, @Events[0], False, WSA_INFINITE, False);
Index:=Ret-WSA_WAIT_EVENT_0;
for i:=Index to ConnectionNum-1 do
begin
Ret:=WSAWaitForMultipleEvents(1, @Events, True, 0, False);
if (Ret=WSA_WAIT_FAILED) or (Ret=WSA_WAIT_TIMEOUT) then
Continue;
if WSAEnumNetworkEvents(Connection, Events, @NetworkEvent)=SOCKET_ERROR then
Continue;
if (NetworkEvent.lNetworkEvents and FD_ACCEPT)<>0 then
begin
if NetworkEvent.iErrorCode[FD_ACCEPT_BIT]<>0 then
begin
WriteLn('FD_ACCEPT failed with error ', NetworkEvent.iErrorCode[FD_ACCEPT_BIT]);
Continue
end;
if ConnectionNum<=MaxConnection then
begin
ClientAddrLen:=SizeOf(ClientAddr);
Connection[ConnectionNum]:=accept(Connection, ClientAddr, ClientAddrLen);
if Connection[ConnectionNum]=INVALID_SOCKET then
begin
WriteLn('accept failed with error ', WSAGetLastError);
Continue
end;
Events[ConnectionNum]:=WSACreateEvent;
if Events[ConnectionNum]=WSA_INVALID_EVENT then
begin
WriteLn('WSACreateEvent failed with error ', WSAGetLastError);
if closesocket(Connection[ConnectionNum])=SOCKET_ERROR then
WriteLn('closesocket failed with error ', WSAGetLastError);
Continue
end;
if WSAEventSelect(Connection[ConnectionNum], Events[ConnectionNum], FD_READ or FD_CLOSE)=SOCKET_ERROR then
begin
WriteLn('WSAEventSelect failed with error ', WSAGetLastError);
if closesocket(Connection[ConnectionNum])=SOCKET_ERROR then
WriteLn('closesocket failed with error ', WSAGetLastError);
if not WSACloseEvent(Events[ConnectionNum]) then
WriteLn('WSACloseEvent failed with error ', WSAGetLastError);
Continue
end;
WriteLn('accetp ', inet_ntoa(ClientAddr.sin_addr), ':', ntohs(ClientAddr.sin_port));
Inc(ConnectionNum)
end
end;
if (NetworkEvent.lNetworkEvents and FD_READ)<>0 then
begin
if NetworkEvent.iErrorCode[FD_READ_BIT]<>0 then
begin
WriteLn('FD_READ failed with error ', NetworkEvent.iErrorCode[FD_READ_BIT]);
Continue
end;
SetLength(Buf, BufSize);
Ret:=recv(Connection, Buf[1], BufSize, 0);
if Ret=SOCKET_ERROR then
begin
WriteLn('recv failed with error ', WSAGetLastError);
Continue
end;
SetLength(Buf, Ret);
ClientAddrLen:=SizeOf(ClientAddr);
if getpeername(Connection, ClientAddr, ClientAddrLen)=SOCKET_ERROR then
begin
WriteLn('getpeername failed with error ', WSAGetLastError);
Continue
end;
Buf:='來自'+inet_ntoa(ClientAddr.sin_addr)+':'+IntToStr(ntohs(ClientAddr.sin_port))+' '+Buf;
Buf:=TimeToStr(Time)+' '+Buf;
for j:=1 to ConnectionNum do
if send(Connection[j], Buf[1], Length(Buf), 0)=SOCKET_ERROR then
begin
WriteLn('send failed with error ', WSAGetLastError);
Continue
end;
WriteLn(Buf)
end;
if (NetworkEvent.lNetworkEvents and FD_CLOSE)<>0 then
begin
if NetworkEvent.iErrorCode[FD_CLOSE_BIT]<>0 then
begin
WriteLn('FD_CLOSE failed with error ', NetworkEvent.iErrorCode[FD_CLOSE_BIT]);
Continue
end;
ClientAddrLen:=SizeOf(ClientAddr);
if getpeername(Connection, ClientAddr, ClientAddrLen)=SOCKET_ERROR then
begin
WriteLn('getpeername failed with error ', WSAGetLastError);
Continue
end;
Buf:='closesocket '+inet_ntoa(ClientAddr.sin_addr)+':'+IntToStr(ntohs(ClientAddr.sin_port));
WriteLn(Buf);
if closesocket(Connection)=SOCKET_ERROR then
WriteLn('closesocket failed with error ', WSAGetLastError);
if not WSACloseEvent(Events) then
WriteLn('WSACloseEvent failed with error ', WSAGetLastError);
if ConnectionNum>1 then
begin
Connection:=Connection[ConnectionNum-1];
Events:=Events[ConnectionNum-1];
Dec(ConnectionNum)
end
end
end
end;
for i:=0 to ConnectionNum do
if closesocket(Connection)=SOCKET_ERROR then
begin
WriteLn('closesocket failed with error ', WSAGetLastError);
ReadLn;
Exit
end;
if WSACleanup=SOCKET_ERROR then
begin
WriteLn('WSCleanup failed with error ', WSAGetLastError);
ReadLn;
Exit
end
end.
相關文章
- 【TCP/IP】TCP伺服器併發處理&原始碼TCP伺服器原始碼
- 轉一篇OpenSSL的例子:簡單的TLS伺服器TLS伺服器
- TCP併發伺服器的程式設計實現TCP伺服器程式設計
- NET平臺下TCP實現IOCP例子TCP
- centos上nginx轉發tcp請求CentOSNginxTCP
- 計算機網路再次整理————tcp例子[五]計算機網路TCP
- 發郵件的例子
- 限制單個IP併發TCP連線的方法(轉)TCP
- 軟體開發中的矛盾——一個簡單的例子 (轉)
- 計算機網路再次整理————tcp例子前奏[三]計算機網路TCP
- [TCP]轉TCP相關知識TCP
- 玩轉TCPTCP
- 行列轉換的一個例子
- 用 API 做的 ServerSocket 例子 (轉)APIServer
- JavaMail 傳送附件的例子 (轉)JavaAI
- 一個可逆加密的例子 (轉)加密
- TCP伺服器虛擬串列埠工具的MCGS開發除錯教程TCP伺服器串列埠除錯
- Golang 編寫 Tcp 伺服器GolangTCP伺服器
- [UNP] TCP 多程式伺服器TCP伺服器
- Swoole 建立TCP ECHO伺服器TCP伺服器
- TabStrip應用例子 (轉)
- 配置支援高併發TCP連線的Linux伺服器全攻略TCPLinux伺服器
- windows 環境 tcp/udp 埠轉發(草稿待寫)WindowsTCPUDP
- 一個sql的行列轉置的例子SQL
- 計算機網路再次整理————tcp例子第二前奏[四]計算機網路TCP
- 建立dns轉發伺服器DNS伺服器
- 在TCP三次握手後插入偽造的TCP包(轉)TCP
- 完整的oraclerman備份恢復的例子(轉)Oracle
- Nginx querystring 轉寫的兩個例子Nginx
- iPhone 呼叫Web Service 例子(轉)iPhoneWeb
- Unity如何連線伺服器: 一個簡單的例子Unity伺服器
- 利用“TCP/IP篩選”功能限制伺服器的埠TCP伺服器
- Swoole學習(二)Swoole之TCP伺服器的建立TCP伺服器
- 匯川Easy521的TCP伺服器通訊TCP伺服器
- 單臺伺服器最大tcp連線伺服器TCP
- netty搭建Tcp伺服器實踐NettyTCP伺服器
- libuv中實現tcp伺服器TCP伺服器
- 小例子 理解 Laravel 中的 控制反轉模式Laravel模式