Хочу показать довольно полезный пример работы сокета, основанный на сообщениях. Приемущество его в том, что не нужно по циклу опрашивать сокет на предмет принятия данных и т.д., сокет сам сообщит об этом. Для реализации требуется winsock2, обертку под Делфи можно легко найти в рунете. Первым делом объявляется константа Code: WM_SocketEvent = WM_User+112; которая будет выполнять функции идентификатора сообщения от сокета (присваивается любое значение, не занятое стандартными сообщениями Windows). Далее идет стандартная последовательность - подготовка сокета к прослушиванию Code: if WSAStartup(MAKEWORD(2,0),WSA)=0 then begin Sock:=socket(AF_INET,SOCK_STREAM,0); if Sock=INVALID_SOCKET then //error and exit address.sin_addr.s_addr := htonl(INADDR_ANY); address.sin_family:=AF_INET; address.sin_port:=htons(portnum); FillChar(Address.sin_zero,SizeOf(Address.sin_zero),0); if bind(Sock, @address, sizeof(address))=SOCKET_ERROR then //error and exit end; А вот и самое главное: перед непосредственным началом слушания порта (командой listen) сокет переводится в неблокирующий режим и привязывается к хэндлу, куда впоследствии будут отправляться сообщения. Code: WSAAsyncSelect(Handle,WM_SocketEvent,FD_Read or FD_Accept or FD_Close); Таким образом, при поступлении данных от клиентов (FD_Read), коннекте и дисконнекте (FD_Accept и FD_Close соответственно) будут генерироваться сообщения с идентификатором WM_SocketEvent, отправленные на хэндл Handle (лучше всего использовать хэндл формы, если это GUI-приложение). Остается только правильно принять эти сообщения и обработать. Создается обработчик сообщений WM_SocketEvent, Wparam сообщения будет содержать хэндл на клиентский сокет (еще один плюс - не надо хранить информацию о клиентских сокетах, при возникновении события мы сразу можем узнать, какой из клиентов его вызвал). LParam будет указывать на тип события: Code: WSAGetSelectEvent(lParam) возвратит один из типов события, в данном случае это либо FD_Read, либо FD_Accept, либо FD_Close. Таким образом, примерный вид обработчика сообщений будет таким: Code: private procedure SocketProc(var Msg: TMessage); message WM_SocketEvent; ... procedure SocketProc(var Msg: TMessage); var sClient:TSocket; begin inherited ; if Msg.Msg = WM_SocketEvent then begin Sclient := Msg.Wparam; case WSAGetSelectEvent(Msg.lParam) of FD_Read: begin recv(Sclient,буфер,размер_буфера,0); end; FD_Accept: begin Accept(...); MessageBox(Клиент такой-то подключился); end; FD_Close: begin MessageBox(Клиент такой-то отключился); end; end; end; Рульная вещь, всем советую попробовать, кто не пользовался.