有个VC的例子,你拿去参考一下,看能不能改成DELPHI的
#include <stdio.h>
#include <winsock2.h>
#include <stdlib.h>
#pragma comment (lib,"WS2_32.lib"
#define SERV_TCP_PORT 9999
#define DATA_BUFSIZE 1024
struct _OVERLAPPELUS
{
SOCKET socket;
char InBuffer[DATA_BUFSIZE]; // 输入
OVERLAPPED ovIn;
int nOutBufIndex;
char OutBuffer[DATA_BUFSIZE]; // 输出
OVERLAPPED ovOut;
DWORD dwWritten;
}OVERLAPPELUS, *LPOVERLAPPELUS;
_OVERLAPPELUS pKey;
HANDLE ghCompletionPort;
void CreateWorkerThreads();
DWORD WINAPI WorkerThread(LPVOID pvoid);
void IssueRead(struct _OVERLAPPELUS *pCntx);
void CheckOsVersion();
void FatalError(char *s);
void SendString(char *p,struct _OVERLAPPELUS *pCntx);
///////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
SOCKET listener;
SOCKET newsocket;
WSADATA WsaData;
struct sockaddr_in serverAddress;
int err;
CheckOsVersion();
err = WSAStartup (0x0202, &WsaData);
if (err == SOCKET_ERROR)
{
FatalError("网络初始化失败."
;
return EXIT_FAILURE;
}
if ((listener = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d/n", WSAGetLastError());
return EXIT_FAILURE;
}
memset(&serverAddress, 0, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(SERV_TCP_PORT);
err = bind(listener, (struct sockaddr *)&serverAddress, sizeof(serverAddress));
if (err < 0)
{
FatalError("bind() 错误-请检查 TCP/IP 是否正确安装?"
;
}
ghCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL,0,0);
if (ghCompletionPort == NULL)
{
FatalError("CreateIoCompletionPort() 错误-请检查系统是否是Windows NT version 3.51 或更高版本."
;
}
CreateWorkerThreads();
listen(listener, 5);
fprintf(stderr, "I/O Completion Ports 模式:端口 %d/n", SERV_TCP_PORT);
fprintf(stderr, "Ctrl+C 停止服务器程序/n"
;
printf("written by http://www.wantsoft.com/n"
;
fprintf(stderr, "开始监听客户端:/n"
;
// 无限循环,接受并处理新的连接
while (true)
{
if ((newsocket = WSAAccept(listener, NULL, NULL, NULL, 0)) == SOCKET_ERROR)
{
printf("WSAAccept() failed with error %d/n", WSAGetLastError());
return EXIT_FAILURE;
}
//建立一个 key 并初始化它.
pKey.socket = newsocket;
pKey.ovOut.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); //为写信息包过程设置(事件对象) event .
pKey.ovOut.hEvent = (HANDLE)((DWORD)pKey.ovOut.hEvent | 0x1);
CreateIoCompletionPort( //为请求绑定端口
(HANDLE)newsocket,
ghCompletionPort,
(DWORD)&pKey,
0 );
IssueRead(&pKey); // 完成第一次读操作
}
return 0;
}
void CreateWorkerThreads()
{
SYSTEM_INFO sysinfo;
DWORD dwThreadId;
DWORD dwThreads;
DWORD i;
GetSystemInfo(&sysinfo);
dwThreads = sysinfo.dwNumberOfProcessors * 2 + 2;
for (i=0; i<dwThreads; i++)
{
HANDLE hThread;
hThread = CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId);
CloseHandle(hThread);
}
}
// 每一个工作线程从这里开始.
DWORD WINAPI WorkerThread(LPVOID pVoid)
{
BOOL bResult;
DWORD dwNumRead;
struct _OVERLAPPELUS *pCntx;
LPOVERLAPPED lpOverlapped = NULL;
UNREFERENCED_PARAMETER(pVoid);
// 无限循环从 I/O completion port 获取信息.
while (true)
{
bResult = GetQueuedCompletionStatus(ghCompletionPort, &dwNumRead, (DWORD*)&pCntx, &lpOverlapped, INFINITE);
if (bResult == FALSE && lpOverlapped == NULL)
{
FatalError("WorkerThread - GetQueuedCompletionStatus()错误./n"
;
}
else if (bResult == FALSE && lpOverlapped != NULL)
{
fprintf(stderr,"用户非正常退出./n"
;
}
else if (dwNumRead == 0)
{
fprintf(stderr, "用户已经退出./n"
;
fprintf(stderr, "------------------./n"
;
}
else
{
printf("recv data from client: %s/n", pCntx->InBuffer);
SendString(pCntx->InBuffer, pCntx);
IssueRead(pCntx);
}
}
ExitThread(0);
return 0;
}
///////////////////////////////////////////////////////
//调用 WSARecv 开始一个异步请求重复获取我们的句柄状态//
///////////////////////////////////////////////////////
void IssueRead(struct _OVERLAPPELUS *pCntx)
{
DWORD RecvBytes;
DWORD Flags =0;
WSABUF DataBuff;
if (pCntx == NULL)
return;
memset(pCntx->InBuffer, 0, sizeof(pCntx->InBuffer));
ZeroMemory( &(pCntx->ovIn), sizeof(OVERLAPPED));
DataBuff.len = DATA_BUFSIZE;
DataBuff.buf = pCntx->InBuffer;
if (WSARecv(pCntx->socket, &DataBuff, 1, &RecvBytes, &Flags,
&(pCntx->ovIn), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d/n", WSAGetLastError());
return ;
}
}
}
// 确保我们运行在正确的版本下 Windows NT (3.51, 4.0, or later)
void CheckOsVersion()
{
OSVERSIONINFO ver;
BOOL bResult;
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
bResult = GetVersionEx((LPOSVERSIONINFO) &ver);
if ( (!bResult) ||
(ver.dwPlatformId != VER_PLATFORM_WIN32_NT) )
{
FatalError("ECHOSRV requires Windows NT 3.51 or later."
;
}
}
//发送字符串子程序
void SendString(char *p, struct _OVERLAPPELUS *pCntx)
{
DWORD SendBytes;
WSABUF DataBuff;
int len;
strcpy(pCntx->OutBuffer,p);
len = strlen(pCntx->OutBuffer);
pCntx->OutBuffer[len] = '/0';
pCntx->nOutBufIndex = strlen(pCntx->OutBuffer);
DataBuff.len = len;
DataBuff.buf = pCntx->OutBuffer;
if (WSASend(pCntx->socket, &DataBuff, 1, &SendBytes, 0,
&(pCntx->ovOut), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSASend() failed with error %d/n", WSAGetLastError());
return ;
}
}
}
// 错误句柄
void FatalError(char *s)
{
fprintf(stdout, "%s/n", s);
exit(EXIT_FAILURE);
}