Обе connect()
и bind()
системные вызовы «ассоциировать» сокет дескриптор файла на адрес (обычно это IP / порт комбинации). Их прототипы похожи на: -
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
и
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
В чем точная разница между 2 звонками? Когда следует использовать connect()
и когда bind()
?
В частности, в некоторых примерах клиентских кодов сервера обнаружено, что клиент использует, connect()
а сервер использует bind()
вызов. Причина была мне не совсем ясна.
c
sockets
network-programming
Сиддхартха Гош
источник
источник
Ответы:
Чтобы лучше понять, давайте выясним, где именно происходит связывание и соединение,
В дополнение к позиционированию двух звонков, как пояснил Сурав,
bind () связывает сокет с его локальным адресом [вот почему выполняется привязка на стороне сервера, чтобы клиенты могли использовать этот адрес для подключения к серверу.] connect () используется для подключения к удаленному адресу [сервера], поэтому на стороне клиента , используется подключение [читается как: подключение к серверу].
Мы не можем использовать их взаимозаменяемо (даже если у нас есть клиент / сервер на одном компьютере) из-за определенных ролей и соответствующей реализации.
Далее я порекомендую соотнести эти вызовы с рукопожатием TCP / IP.
Итак, кто отправит сюда SYN, это будет connect (). В то время как bind () используется для определения конечной точки связи.
Надеюсь это поможет!!
источник
Один лайнер:
bind()
на собственный адрес,connect()
на удаленный адрес.Цитата из справочной страницы
bind()
и из того же для
connect()
Чтобы уточнить,
bind()
связывает сокет с его локальным адресом [поэтому на стороне сервераbind
s, чтобы клиенты могли использовать этот адрес для подключения к серверу.]connect()
используется для подключения к удаленному [серверу] адресу, поэтому на стороне клиента используется подключение [читается как: подключение к серверу].источник
interchangeable
local
-> сам процесс,remote
-> другой процесс.bind сообщает запущенному процессу требовать порт. т.е. он должен привязаться к порту 80 и прослушивать входящие запросы. с bind ваш процесс становится сервером. когда вы используете connect, вы говорите своему процессу подключиться к порту, который УЖЕ используется. ваш процесс становится клиентом. разница важна: bind хочет порт, который не используется (чтобы он мог потребовать его и стать сервером), а connect хочет порт, который уже используется (чтобы он мог подключиться к нему и поговорить с сервером)
источник
Из Википедии http://en.wikipedia.org/wiki/Berkeley_sockets#bind.28.29
подключения ():
Системный вызов connect () подключает сокет, идентифицированный его файловым дескриптором, к удаленному хосту, указанному адресом этого хоста в списке аргументов.
Определенные типы сокетов являются сокетами без установления соединения, чаще всего это сокеты протокола пользовательских дейтаграмм. Для этих сокетов соединение имеет особое значение: цель по умолчанию для отправки и получения данных устанавливается на заданный адрес, что позволяет использовать такие функции, как send () и recv () для сокетов без установления соединения.
connect () возвращает целое число, представляющее код ошибки: 0 представляет успех, а -1 представляет ошибку.
Bind ():
bind () назначает сокет адресу. Когда сокет создается с помощью socket (), ему предоставляется только семейство протоколов, но не назначается адрес. Это сопоставление с адресом должно быть выполнено с помощью системного вызова bind (), прежде чем сокет сможет принимать соединения с другими хостами. bind () принимает три аргумента:
sockfd, дескриптор, представляющий сокет для выполнения привязки. my_addr, указатель на структуру sockaddr, представляющую адрес для привязки. addrlen, поле socklen_t, определяющее размер структуры sockaddr. Bind () возвращает 0 в случае успеха и -1 в случае ошибки.
Примеры: 1.) Использование Connect
2.) Пример привязки:
Надеюсь, это проясняет разницу
Обратите внимание, что тип сокета, который вы объявляете, будет зависеть от того, что вам нужно, это чрезвычайно важно.
источник
Я думаю, что это поможет вашему пониманию, если вы будете думать о
connect()
иlisten()
как о двойниках, а не оconnect()
иbind()
. Причина в том, что вы можете вызвать или опуститьbind()
перед любым из них, хотя редко бывает хорошей идеей вызывать его раньшеconnect()
или не вызывать его раньшеlisten()
.Если это помогает мыслить категориями серверов и клиентов, то
listen()
это отличительная черта как первого, так иconnect()
второго.bind()
можно найти - или не найти - ни на одном из них.Если мы предположим, что наш сервер и клиент находятся на разных машинах, становится легче понять различные функции.
bind()
действует локально, то есть привязывает конец соединения на машине, на которой он вызывается, к запрошенному адресу и назначает запрошенный порт вам. Это происходит независимо от того, будет эта машина клиентом или сервером.connect()
инициирует соединение с сервером, то есть подключается к запрошенному адресу и порту на сервере от клиента. Этот сервер почти наверняка будет звонитьbind()
раньшеlisten()
, чтобы вы могли узнать, по какому адресу и какому порту подключаться к нему с помощьюconnect()
.Если вы не позвоните
bind()
, порт и адрес будут неявно назначены и привязаны к локальной машине для вас, когда вы вызываете либоconnect()
(клиент), либоlisten()
(сервер). Однако это побочный эффект обоих, а не их цель. Назначенный таким образом порт недолговечен.Важным моментом здесь является то, что привязка клиента не требуется, поскольку клиенты подключаются к серверам, и поэтому сервер будет знать адрес и порт клиента, даже если вы используете временный порт, а не привязку к чему-то конкретному. С другой стороны, хотя сервер может вызывать
listen()
без вызоваbind()
, в этом сценарии ему нужно будет обнаружить назначенный им эфемерный порт и передать его любому клиенту, который хочет к нему подключиться.Я предполагаю, что, когда вы упомянули,
connect()
что вас интересует TCP, но это также переносится на UDP, где не вызываяbind()
до первогоsendto()
(UDP без подключения) также приводит к неявному назначению и привязке порта и адреса. Одна функция, которую вы не можете вызвать без привязки, - это функцияrecvfrom()
, которая вернет ошибку, потому что без назначенного порта и привязанного адреса нет ничего (или слишком много, в зависимости от того, как вы интерпретируете отсутствие привязки).источник
Слишком долго; Не читать: разница в том, устанавливается ли адрес / порт источника (локальный) или назначения. Короче говоря,
bind()
установите источник иconnect()
установите пункт назначения. Вне зависимости от TCP или UDP.bind()
bind()
установить локальный (исходный) адрес сокета. Это адрес, по которому принимаются пакеты. Пакеты, отправленные сокетом, несут это как адрес источника, поэтому другой хост будет знать, куда отправлять свои пакеты.Если получение не требуется, адрес источника сокета бесполезен. Протоколы, такие как TCP, требуют включения приема для правильной отправки, поскольку хост-адресат отправляет подтверждение, когда прибыл один или несколько пакетов (т. Е. Подтверждение).
connect()
connect()
запускает код TCP, чтобы попытаться установить соединение с другой стороной.connect()
только установить адрес по умолчанию для отправки пакетов, когда адрес не указан. Когдаconnect()
не используется,sendto()
илиsendmsg()
должен использоваться, содержащий адрес назначения.Когда
connect()
или вызывается функция отправки, и адрес не привязан, Linux автоматически привязывает сокет к случайному порту. Технические подробности см. Вinet_autobind()
исходном коде ядра Linux.Боковые примечания
listen()
только TCP.struct sockaddr_in
) состоит из IP-адреса (см. Заголовок IP ) и порта TCP или UDP (см. Заголовок TCP и UDP ).источник