Работа
с сокетами
В этой главе мы рассмотрим
некоторые сетевые возможности, предоставляемые средой Kylix на примере работы
с сокетами.
Сокеты — это специальные
компоненты, позволяющие вашему приложению соединяться с другими компьютерами,
использующими сетевой протокол TCP/IP. Кроме того, сокеты дают возможность работать
и с другими сетевыми протоколами, такими как XNS (Xerox Network System), DECnet
и Novell IPX/SPX.
Используя сокеты, вы можете
читать или посылать данные на другие компьютеры, не беспокоясь об установленном
на компьютерах сетевом программном обеспечении. То есть сокеты предоставляют
интерфейс между приложением-клиентом или приложением-сервером и сетевым программным
обеспечением, установленным на данном компьютере.
Таким образом, сокеты позволяют
создавать приложения как для клиентов, так и для серверов сети. Эти приложения
могут предоставлять один из двух сервисов: Hypertext Transfer Protocol (HTTP)
или File Transfer Protocol (FTP)
Перед написанием приложения
клиента или сервера сети вы должны знать, какие услуги будет предоставлять ваше
приложение, если это приложение-сервер, или какие услуги будет получать приложение-клиент.
Если вы используете стандартные протоколы, такие как HTTP или FTP, то вопрос
о предоставляемых услугах обычно не возникает.
Большинство стандартных
услуг протоколов ассоциированы, по соглашению, с определенными номерами портов.
Для получения конкретной услуги вы должны указать номер порта и цифровой код
услуги. Если вы используете стандартные услуги, предоставляемые компонентом-сокетом
TTCPClient, то он самостоятельно определит номер порта для нужной услуги. Если
вы создаете собственные услуги, вы должны указать ассоциированный с ней номер
порта в файле /etc/services. Данный файл представляет собой ASCII-файл, содержащий
список сетевых услуг, включая их имя, номер порта и тип протокола передачи данных
(листинг 11.1).
Листинг 11.1.Список
сетевых услуг,содержащийся в файле services
# /etc/services:
# $Id:
services,v 1.4 2000/05/15 15:54:48 chmouel Exp $
#
# Сетевые
услуги Интернет
#
#
номера портов как для TCP, так и для UDP; большинство портов используют
#
оба эти протокола.
#
Обновлено RFC 1700, ``Ассоциированные номера" (Октябрь 1994).
#
Не все порты включены в список, только наиболее используемые.
tcpmux 1/tcp
echo 7/tcp
echo 7/udp
discard 9/tcp sink null
discard 9/udp sink null
systat 11/tcp users
daytime 13/tcp
daytime 13/udp
netstat 15/tcp
qotd 17/tcp quote
msp 18/tcp # протокол отправки сообщений
msp 18/udp # протокол отправки сообщений
chargen 19/tcp ttytst source
chargen 19/udp ttytst source
ftp-data 20/tcp
ftp 21/tcp
fsp 21/udp fspd
ssh 22/tcp # SSH удаленный протокол авторизации
ssh 22/udp # SSH удаленный протокол авторизации
telnet 23/tcp
# 24 - для частного использования smtp 25/tcp mail
# 26 - не назначен
time 37/tcp timserver
time 37/udp timserver
rlp 39/udp resource # расположение ресурсов
nameserver 42/tcp name # IEN 116
whois 43/tcp nicname
re-mail-ck 50/tcp # Удаленный протокол проверки почты
re-mail-ck 50/udp # Удаленный протокол проверки почты
domain 53/tcp nameserver # имя сервера домена
domain 53/udp nameserver
mtp 57/tcp
bootps 67/tcp # ВООТР-сервер
bootps 67/udp
bootpc 68/tcp # ВООТР-клиент
bootpc 68/udp
tftp 69/udp
gopher 70/tcp # Internet Gopher
gopher 70/udp
rje 77/tcp netrjs
finger 79/tcp
www 80/tcp http # WorldWideWeb HTTP
www 80/udp # HyperText Transfer Protocol
link 87/tcp ttylink
kerberos 88/tcp kerberos5 krb5 # Kerberos v5
kerberos 88/udp kerberos5 krb5 # Kerberos v5
supdup 95/tcp
# 100 - reserved
hostnames 101/tcp hostname
iso-tsap 102/tcp tsap # часть ISODE.
csnet-ns 105/tcp cso-ns
csnet-ns 105/udp cso-ns
# poppassd (Eudora) использует порты, которые уже были ассоциированы
# с другими услугами. Ниже приведен список poppassd.
# Это позволяет программам запрашивать данные услуги.
rtelnet 107/tcp # удаленный Telnet
rtelnet 107/udp
pop2 109/tcp pop-2 postoffice # POP версии 2
pop2 109/udp pop-2
рор3 110/tcp pop-3 # POP версии 3
рор3 110/udp pop-3
sunrpc 111/tcp portmapper # RPC 4.0 portmapper TCP
sunrpc 111/udp portmapper # RPC 4.0 portmapper UDP
auth 113/tcp authentication tap ident
sftp 115/tcp
uucp-path 117/tcp
nntp 119/tcp readnews untp # USENET News Transfer Protocol
ntp 123/tcp
ntp 123/udp # Network Time Protocol
netbios-ns 137/tcp # имя сервиса NETBIOS
netbios-ns 137/udp
netbios-dgm 138/tcp # NETBIOS Datagram-услуга
netbios-dgm 138/udp
netbios-ssn 139/tcp
netbios-ssn 139/udp
imap2 143/tcp imap # Interim Mail Access Proto v2
imap2 143/udp imap
snmp 161/udp # Simple Net Mgmt Proto
snmp-trap 162/udp snmptrap
cmip-man 163/tcp
cmip-man 163/udp
cmip-agent 164/tcp
amp-agent 164/udp
xdmcp 177/tcp # X Display Mgr. Control Proto
xdmcp 177/udp
nextstep 178/tcp NeXTStep NextStep # Окно NeXTStep
nextstep 178/udp NeXTStep NextStep # сервер
bgp 179/tcp # Border Gateway Proto.
bgp 179/udp
prospero 191/tcp # Cliff Neuman's Prospero
prospero 191/udp
irс 194/tcp # Internet Relay Chat
irc 194/udp
smux 199/tcp # SNMP Unix Multiplexer
smux 199/udp
at-rtmp 201/tcp # маршрутизация AppleTalk
at-rtmp 201/udp
at-nbp 202/tcp # привязка имен AppleTalk
at-nbp 202/udp
at-echo 204/tcp # эхо AppleTalk
at-echo 204/udp
at-zis 206/tcp # информация о часовом поясе AppleTalk
at-zis 206/udp
qmtp 209/tcp # The Quick Mail Transfer Protocol
qmtp 209/udp # The Quick Mail Transfer Protocol
z3950 210/tcp wais # база данных NISO Z39.50
z3950 210/udp wais
ipx 213/tcp # IPX
ipx 213/udp
imap3 220/tcp # Interactive Mail Access
imap3 220/udp # Protocol v3
rpc2portmap 369/tcp
rpc2portmap 369/udp # Coda portmapper
codaauth2 370/tcp
codaauth2 370/udp # сервер авторизации Coda
ulistserv 372/tcp # UNIX Listserv
ulistserv 372/udp
ldap 389/tcp # Lightweight Directory Access Protocol
ldap 389/udp # Lightweight Directory Access Protocol
https 443/tcp # MCom
https 443/udp # MCom
snpp 444/tcp # Simple Network Paging Protocol
snpp 444/udp # Simple Network Paging Protocol
saft 487/tcp ft Simple Asynchronous File Transfer
saft 487/udp # Simple Asynchronous File Transfer
npmp-local 610/tcp dqs313_qmaster # npmp-local / DQS
npmp-local 610/udp dqs313_qmaster # npmp-local / DQS
npmp-gui 611/tcp dqs313_execd # npmp-gui / DQS
npmp-gui
611/udp dqs313_execd ft npmp-gui / DQS
hmmp-ind
612/tcp dqs313_intercell# HMMP Indication / DQS
hmmp-ind
612/udp dqs313_intercell# HMMP Indication / DQS
#
# Особые
сервисы UNIX
#
exec
512/tcp
biff
512/udp comsat
login
513/tcp
who 513/udp
whod
shell
514/tcp and # без использования пароля
syslog
514/udp
printer
515/tcp spooler # линейный пул принтера
talk
517/tcp
ntalk
518/udp
route
520/udp router routed # RIP
timed
525/udp timeserver
tempo
526/tcp newdate
courier
530/tcp rpc
conference
531/tcp chat
netnews
532/tcp readnews
netwall
533/udp # для непредвиденных передач
uucp
540/tcp uucpd # uucp daemon
afpovertcp
548/tcp # AFP над TCP
afpovertcp
548/udp # AFP над TCP
remotefs
556/tcp rfs_server rfs # удаленная файловая система Brunhoff
klogin
543/tcp # Kerberized `rlogin' (v5)
kshell
544/tcp krcmd # Kerberized `rsh' (v5)
kerberos-adm
749/tcp. # Kerberos `kadmin' (v5)
#
webster
765/tcp # сетевой словарь
webster
765/udp
#
#
ingreslock
1524/tcp
ingreslock
1524/udp
prospero-np
1525/tcp # Prospero non-privileged
prospero-np
1525/udp
datametrics
1645/tcp old-radius # datametrics / старый радиус вхождения
datametrics
1645/udp old-radius # datametrics / старый радиус вхождения
sa-msg-port
1646/tcp old-radacct # sa-msg-port / старый radacct вхождения
sa-msg-port
1646/udp old-radacct # sa-msg-port / старый radacct вхождения
radius
1812/tcp # радиус
radius
1812/udp # радиус
radacct
1813/tcp # радиус учета
radacct
1813/udp # радиус учета
cvspserver
2401/tcp # CVS client/server operations
cvspserver
2401/udp # CVS client/server operations
venus
2430/tcp # codacon port
venus
2430/udp # Venus callback/wbc interface
venus-se
2431/tcp # tcp side effects
venus-se
2431/udp # udp sftp side effect
codasrv
2432/fccp # не используется
codasrv
2432/udp # порт сервера
codasrv-se
2433/tcp # tcp side effects
codasrv-se
2433/udp # udp sftp side effect
mysql
3306/tcp # MySQL
mysql
3306/udp # MySQL
rfe 5002/tcp
# Radio Free Ethernet
rfe 5002/udp
# Используется только UDP
cfengine
5308/tcp # CFengine
cfengine
5308/udp # CFengine
bbs 7000/tcp
# BBS
#
#
kerberos4
750/udp kerberos-iv kdc # Kerberos (сервер) udp
kerberos4
750/tcp kerberos-iv kdc # Kerberos (сервер) tcp
kerberos_master
751/udp # Kerberos авторизация
kerberos_master
751/tcp # Kerberos авторизация
passwd_server
752/udp # Kerberos сервер passwd
krb_prop
754/tcp # Kerberos
krbupdate
760/tcp kreg # регистрация Kerberos
kpasswd
761/tcp kpwd # Kerberos "passwd"
kpop
1109/tcp # Kerberos
knetd
2053/tcp # Kerberos
zephyr-srv
2102/udp # сервер Zephyr
zephyr-clt
2103/udp # Zephyr serv-hm -соединение
zephyr-hm
2104/udp # Zephyr менеджер хоста
eklogin
2105/tcp # Kerberos зашифрованный rlogin
#
# Неофициальные,
но необходимые (для NetBSD) услуги
#
supfilesrv
871/tcp # сервер SUP
supfiledbg
1127/tcp # отладчик SUP
#
# Услуги
протокола Datagram Delivery
#
rtmp
1/ddp
nbp 2/ddp
# Протокол связывания имен
echo
4/ddp # Эхо-протокол AppleTalk
zip
6/ddp # Протокол часового пояса
#
# Услуги,
добавленные для Debian GNU/Linux
#
poppassd
106/tcp # Eudora
poppassd
106/udp # Eudora
mailq
174/udp
mailq
174/tcp
ssmtp
465/tcp # SMTP над SSL
gdomap
538/tcp # распределенные объекты GNUstep
gdomap
538/udp # распределенные объекты GNUstep
snews
563/tcp # NNTP над SSL
ssl-ldap
636/tcp # LDAP над SSL
omirr
808/tcp omirrd # Онлайн-зеркало
omirr
808/udp omirrd # Онлайн-зеркало
rsync
873/tcp # rsync
rsync
873/udp # rsync
swat
901/tcp # inetd
simap
993/tcp # IMAP над SSL
sрор3
995/tcp # POP-3 над SSL
socks 1080/tcp
# socks-прокси сервер
socks
1080/udp # socks-прокси сервер
rmtcfg
1236/tcp # Удаленный сервер конфигурирования
xtel
1313/tcp # minitel
support
1529/tcp # GNATS
cfinger
2003/tcp # GNU Finger
ninstall
2150/tcp # услуга ninstall
ninstall
2150/udp # услуга ninstall
afbackup
2988/tcp # система Afbackup
afbackup
2988/udp # система Afbackup
icp 3130/tcp
# Internet Cache Protocol (Squid)
icp 3130/udp
# Internet Cache Protocol (Squid)
postgres
5432/tcp # POSTGRES
postgres
5432/udp # POSTGRES
fax 4557/tcp
# FAX (старый)
hylafax
4559/tcp # HylaFAX (новый)
noclog
5354/tcp # noclogd с TCP (nocol)
noclog
5354/udp # noclogd с UDP (nocol)
hostmon
5355/tcp # hostmon использующий TCP (nocol)
hostmon
5355/udp # hostmon использующий TCP (nocol)
ircd
6667/tcp # Internet Relay Chat
ircd
6667/udp # Internet Relay Chat
webcache
8080/tcp # WWW услуга кэширования
webcache
8080/udp # WWW услуга кэширования
tproxy
8081/tcp # Transparent Proxy
tproxy
8081/udp # Transparent Proxy
mandelspawn
9359/udp mandelbrot # сеть mandelbrot
amanda
10080/udp # Услуга сохранения amanda
kamanda
10081/tcp # Услуга сохранения amanda (Kerberos)
kamanda
10081/udp # Услуга сохранения amanda (Kerberos)
amandaidx
10082/tcp # Услуга сохранения amanda
amidxtape
10083/tcp # Услуга сохранения amanda
isdnlog
20011/tcp # система входа isdn
isdnlog
20011/udp # система входа isdn
vboxd
20012/tcp
vboxd
20012/udp
jserver
22273/tcp
binkp
24554/tcp # Binkley
binkp
24554/udp # Binkley
asp 27374/tcp
# Протокол поиска адреса
asp 27374/udp
# Протокол поиска адреса
tfido
60177/tcp # Ifmail
tfido
60177/udp # Ifmail
fido
60179/tcp # Ifmail
fido
60179/udp # Ifmail
#
# Локальные
услуги
#
linuxconf
98/tcp
Все соединения, использующие сокеты, делятся на три типа:
Как только соединение между
клиентом и сервером устанавливается, сервер и клиент получают одинаковые возможности
и реагируют на одинаковые типы событий. Рассмотрим по порядку эти типы соединений.
Соединение-клиент подключает
сокет-клиент локального компьютера к сокету-серверу на удаленном компьютере.
Соединение создает сокет-клиент. Сначала сокет-клиент должен определить сокет-сервер,
с которым необходимо соединиться. После чего происходит поиск этого сокета и,
если сокет найден, сокет-клиент посылает серверу запрос на соединение. Сокет-сервер
может не установить соединение сразу же после получения запроса. Сервер запоминает
запрос и отвечает на него, как только появляется возможность. Как только сокет-сервер
устанавливает соединение, он отсылает сокету-клиенту свое полное описание, после
чего клиент завершает соединение.
Соединение-сервер прослушивает
запросы сокетов на установление соединения. В случае, если сокет-клиент запрашивает
от сокета-сервера соединение, сокет-сервер отсылает клиенту свое полное описание.
Соединение-слушатель
- это пассивное соединение сервера, которое принципиально отличается от
двух других типов соединений и является односторонним. В этом случае соединение
с сокетами -клиентами не устанавливается, а происходит прослушивание и запись
запросов на соединение, отправляемых сокетами-клиентами.
Каждый сокет может рассматриваться
как конечная точка сетевого соединения. Все сокеты имеют собственные адреса,
которые определяют:
Компоненты для создания
сокетов располагаются на вкладке Internet палитры компонентов Kylix.
Это компоненты TCPClient
и TCPServer.
Компонент TCPClient
позволяет превратить ваше приложение в TCP/IP-клиент. Сокет-клиент позволяет
вам указать сокет-сервер, с которым будет производиться соединение с помощью
свойства RemoteHost
. Данное свойство может содержать как сетевое
имя компьютера, так и его IP-адрес. В дополнение к данному свойству компонент
TCPClient
имеет свойство RemotePort
, которое определяет
номер порта сервера, к которому будет производиться подключение. Вы можете указать
номер порта либо имя услуги.
После установки этих двух
свойств вы можете активизировать ваше соединение с помощью вызова метода open
компонента TCPClient
. Данный метод вызывается во время выполнения
приложения. Если вы хотите, чтобы соединение устанавливалось автоматически после
запуска приложения, установите свойство Active
компонента TCPClient
в true
во время разработки приложения.
Как только соединение установлено,
ваше приложение может отправлять или принимать данные. Передача данных может
осуществляться двумя способами: блоками и асинхронно.
Асинхронная передача
данных — передача данных, не разбитых на отдельные блоки, Для такой передачи
данных установите свойства BlockMode
сокета-клиента и сокета- сервера
в bmNonBlocking
.
Передана данных блоками
осуществляется быстрее, чем асинхронная. Данный способ передачи данных применяется
в тех случаях, когда необходимо продолжать
выполнение приложения во время передачи данных. Таким обра-зом, приложение создает
дополнительный поток для чтения или передачи данных (о процессах и потоках см.
главу 14). Для установки блочного режима передачи данных установите свойства
BlockMode
клиента и сервера bmBlocking.
Для завершения соединения
достаточно произвести вызов метода Close
для компонента TCPClient
.
Кроме того, соединение может быть завершено и со стороны сервера. Если это происходит,
то генерируется событие OnDisconnect
.
Компонент TCPServer
позволяет превратить приложение в ТСР/IР-сервер. Перед тем как сокет-сервер
сможет прослушивать запросы клиентов, вы должны указать номер порта, который
будет прослушивать сервер. Это можно сделать с помощью свойства LocalPort
.
Для начала прослушивания запросов клиентов нужно вызвать метод open компонента
TCPServer
. Для автоматического включения прослушивания во время
запуска приложения установите свойство Active
компонента TCPServer
в true
. Если вы хотите, чтобы сокет-сервер автоматически устанавливал
соединение с клиентом при получении от него запроса, установите свойство AutoAccept
компонента TCPServer
в True
. Для завершения текущего
соединения можно вызвать метод Close
или установить свойство Active
компонента TCPServer
в false
.
Если отключение произведено клиентом, то на сервере произойдет событие OnDisconnect
.
Для передачи данных используйте
функцию SendBuf
. Данная функция описана следующим образом:
function SendBuf(var
buff; bufsize: integer; flags: integer = 0): integer;
dynamic;
При вызове этой функции
приложение отсылает буфер данных через сокет. Переменная buf
—
это переменная, содержащая отсылаемые данные, а bufsize
- размер
буфера данных.
Для приема данных используется
функция ReceiveBuf
:
function ReceiveBuf(var
buf; bufsize: integer; flags: integer =0): integer; dynamic;