소켓 connect () 대 bind ()
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);
두 통화의 정확한 차이점은 무엇입니까? 때 하나를 사용해야 connect()
언제 bind()
?
특히 일부 샘플 서버 클라이언트 코드에서 클라이언트가 사용 connect()
중이고 서버가 bind()
호출을 사용 하고 있음을 발견했습니다 . 이유는 나에게 완전히 명확하지 않았습니다.
이해를 높이기 위해 정확히 바인딩하고 연결하는 위치를 찾아 보겠습니다.
Sourav가 명확히 한 두 호출의 위치 지정에 더하여
bind ()는 소켓을 로컬 주소와 연결합니다. [이것이 서버 측이 바인드하는 이유이므로 클라이언트가 해당 주소를 사용하여 서버에 연결할 수 있습니다.] connect ()는 원격 [서버] 주소에 연결하는 데 사용됩니다. 이것이 클라이언트 측 인 이유입니다. , connect [읽기 : 서버에 연결]이 사용됩니다.
특정 역할과 해당 구현으로 인해 (동일한 컴퓨터에 클라이언트 / 서버가있는 경우에도) 서로 바꿔서 사용할 수 없습니다.
이러한 호출을 TCP / IP 핸드 셰이크로 연결하는 것이 좋습니다.
따라서 여기에 SYN을 보낼 사람은 connect ()입니다. bind ()는 통신 끝점을 정의하는 데 사용됩니다.
도움이 되었기를 바랍니다!!
하나의 라이너 : bind()
자신의 주소로, connect()
원격 주소로.
의 man 페이지에서 인용 bind()
bind ()는 addr에 의해 지정된 주소를 파일 기술자 sockfd가 참조하는 소켓에 할당합니다. addrlen은 addr가 가리키는 주소 구조의 크기 (바이트)를 지정합니다. 전통적으로이 작업을 "소켓에 이름 할당"이라고합니다.
그리고, 동일에서 connect()
connect () 시스템 호출은 파일 설명자 sockfd가 참조하는 소켓을 addr로 지정된 주소에 연결합니다.
명확히하기 위해
bind()
소켓을 로컬 주소와 연결합니다. [bind
그래서 클라이언트가 해당 주소를 사용하여 서버에 연결할 수 있도록 서버 측 이 필요합니다.]connect()
원격 [서버] 주소에 연결하는 데 사용되므로 클라이언트 측에서 연결 [읽기 : 서버에 연결]이 사용됩니다.
bind는 실행중인 프로세스에 포트를 요청하도록 지시합니다. 즉, 자신을 포트 80에 바인딩하고 들어오는 요청을 수신해야합니다. bind를 사용하면 프로세스가 서버가됩니다. connect를 사용할 때 이미 사용중인 포트에 연결하도록 프로세스에 지시합니다. 프로세스가 클라이언트가됩니다. 차이점은 중요합니다. bind는 사용 중이 아닌 포트를 원하고 (권장하고 서버가 될 수 있도록) connect는 이미 사용중인 포트를 원합니다 (따라서 연결하고 서버와 통신 할 수 있음).
Wikipedia에서 http://en.wikipedia.org/wiki/Berkeley_sockets#bind.28.29
잇다():
connect () 시스템 호출은 파일 설명 자로 식별되는 소켓을 인수 목록에서 해당 호스트의 주소로 지정된 원격 호스트에 연결합니다.
특정 유형의 소켓은 비 연결형이며 가장 일반적으로 사용자 데이터 그램 프로토콜 소켓입니다. 이러한 소켓의 경우 connect는 특별한 의미를 갖습니다. 데이터를 보내고 받기위한 기본 대상이 주어진 주소로 설정되어 비 연결 소켓에서 send () 및 recv ()와 같은 함수를 사용할 수 있습니다.
connect ()는 오류 코드를 나타내는 정수를 반환합니다. 0은 성공을 나타내고 -1은 오류를 나타냅니다.
묶다():
bind ()는 소켓을 주소에 할당합니다. socket ()을 사용하여 소켓을 만들면 프로토콜 패밀리 만 제공되고 주소는 할당되지 않습니다. 주소와의이 연결은 소켓이 다른 호스트에 대한 연결을 허용하기 전에 bind () 시스템 호출로 수행되어야합니다. bind ()는 세 가지 인수를 취합니다.
sockfd, 바인드를 수행 할 소켓을 나타내는 설명자. my_addr, 바인딩 할 주소를 나타내는 sockaddr 구조에 대한 포인터. addrlen, sockaddr 구조의 크기를 지정하는 socklen_t 필드. Bind ()는 성공하면 0을 반환하고 오류가 발생하면 -1을 반환합니다.
예 : 1.) Connect 사용
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int main(){
int clientSocket;
char buffer[1024];
struct sockaddr_in serverAddr;
socklen_t addr_size;
/*---- Create the socket. The three arguments are: ----*/
/* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */
clientSocket = socket(PF_INET, SOCK_STREAM, 0);
/*---- Configure settings of the server address struct ----*/
/* Address family = Internet */
serverAddr.sin_family = AF_INET;
/* Set port number, using htons function to use proper byte order */
serverAddr.sin_port = htons(7891);
/* Set the IP address to desired host to connect to */
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.17");
/* Set all bits of the padding field to 0 */
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
/*---- Connect the socket to the server using the address struct ----*/
addr_size = sizeof serverAddr;
connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
/*---- Read the message from the server into the buffer ----*/
recv(clientSocket, buffer, 1024, 0);
/*---- Print the received message ----*/
printf("Data received: %s",buffer);
return 0;
}
2.) 결합 예 :
int main()
{
struct sockaddr_in source, destination = {}; //two sockets declared as previously
int sock = 0;
int datalen = 0;
int pkt = 0;
uint8_t *send_buffer, *recv_buffer;
struct sockaddr_storage fromAddr; // same as the previous entity struct sockaddr_storage serverStorage;
unsigned int addrlen; //in the previous example socklen_t addr_size;
struct timeval tv;
tv.tv_sec = 3; /* 3 Seconds Time-out */
tv.tv_usec = 0;
/* creating the socket */
if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
printf("Failed to create socket\n");
/*set the socket options*/
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
/*Inititalize source to zero*/
memset(&source, 0, sizeof(source)); //source is an instance of sockaddr_in. Initialization to zero
/*Inititalize destinaton to zero*/
memset(&destination, 0, sizeof(destination));
/*---- Configure settings of the source address struct, WHERE THE PACKET IS COMING FROM ----*/
/* Address family = Internet */
source.sin_family = AF_INET;
/* Set IP address to localhost */
source.sin_addr.s_addr = INADDR_ANY; //INADDR_ANY = 0.0.0.0
/* Set port number, using htons function to use proper byte order */
source.sin_port = htons(7005);
/* Set all bits of the padding field to 0 */
memset(source.sin_zero, '\0', sizeof source.sin_zero); //optional
/*bind socket to the source WHERE THE PACKET IS COMING FROM*/
if (bind(sock, (struct sockaddr *) &source, sizeof(source)) < 0)
printf("Failed to bind socket");
/* setting the destination, i.e our OWN IP ADDRESS AND PORT */
destination.sin_family = AF_INET;
destination.sin_addr.s_addr = inet_addr("127.0.0.1");
destination.sin_port = htons(7005);
//Creating a Buffer;
send_buffer=(uint8_t *) malloc(350);
recv_buffer=(uint8_t *) malloc(250);
addrlen=sizeof(fromAddr);
memset((void *) recv_buffer, 0, 250);
memset((void *) send_buffer, 0, 350);
sendto(sock, send_buffer, 20, 0,(struct sockaddr *) &destination, sizeof(destination));
pkt=recvfrom(sock, recv_buffer, 98,0,(struct sockaddr *)&destination, &addrlen);
if(pkt > 0)
printf("%u bytes received\n", pkt);
}
그 차이를 명확히 해주기를 바랍니다.
선언하는 소켓 유형은 필요한 항목에 따라 다르므로 매우 중요합니다.
나는 당신이 생각하는 경우 귀하의 이해를 도울 것이라고 생각 connect()
하고 listen()
대응으로보다는 connect()
하고 bind()
. 그 이유는 bind()
전에 호출하거나 생략 할 수 있기 때문입니다 .하지만 전에 호출하거나 호출 하지 않는 것이 좋은 생각은 거의 connect()
없습니다 listen()
.
If it helps to think in terms of servers and clients, it is listen()
which is the hallmark of the former, and connect()
the latter. bind()
can be found - or not found - on either.
If we assume our server and client are on different machines, it becomes easier to understand the various functions.
bind()
acts locally, which is to say it binds the end of the connection on the machine on which it is called, to the requested address and assigns the requested port to you. It does that irrespective of whether that machine will be a client or a server. connect()
initiates a connection to a server, which is to say it connects to the requested address and port on the server, from a client. That server will almost certainly have called bind()
prior to listen()
, in order for you to be able to know on which address and port to connect to it with using connect()
.
If you don't call bind()
, a port and address will be implicitly assigned and bound on the local machine for you when you call either connect()
(client) or listen()
(server). However, that's a side effect of both, not their purpose. A port assigned in this manner is ephemeral.
An important point here is that the client does not need to be bound, because clients connect to servers, and so the server will know the address and port of the client even though you are using an ephemeral port, rather than binding to something specific. On the other hand, although the server could call listen()
without calling bind()
, in that scenario they would need to discover their assigned ephemeral port, and communicate that to any client that it wants to connect to it.
I assume as you mention connect()
you're interested in TCP, but this also carries over to UDP, where not calling bind()
before the first sendto()
(UDP is connection-less) also causes a port and address to be implicitly assigned and bound. One function you cannot call without binding is recvfrom()
, which will return an error, because without an assigned port and bound address, there is nothing to receive from (or too much, depending on how you interpret the absence of a binding).
Too Long; Don't Read: The difference is whether the source (local) or the destination address/port is being set. In short, bind()
set the source and connect()
set the destination. Regardless of TCP or UDP.
bind()
bind()
set the socket's local (source) address. This is the address where packets are received. Packets sent by the socket carry this as the source address, so the other host will know where to send back its packets.
If receive is not needed the socket source address is useless. Protocols like TCP require receiving enabled in order to send properly, as the destination host send back a confirmation when one or more packets have arrived (i.e. acknowledgement).
connect()
- TCP has a "connected" state.
connect()
triggers the TCP code to try to establish a connection to the other side. - UDP has no "connected" state.
connect()
only set a default address to where packets are sent when no address is specified. Whenconnect()
is not used,sendto()
orsendmsg()
must be used containing the destination address.
경우 connect()
에는 주소가 바인딩되지 않거나 송신 함수가 호출되고, 리눅스는 자동으로 임의의 포트에 소켓을 바인딩합니다. 기술적 세부 사항 inet_autobind()
은 Linux 커널 소스 코드를 참조하십시오.
사이드 노트
listen()
TCP 전용입니다.- 에서 AF_INET의 가족, 소켓의 소스 또는 대상 주소 (
struct sockaddr_in
) IP 주소로 구성된다 ( IP 헤더 ) 및 TCP 또는 UDP 포트 (참조 TCP 및 UDP 헤더를).
참고 URL : https://stackoverflow.com/questions/27014955/socket-connect-vs-bind
'IT story' 카테고리의 다른 글
*를 통해 숨겨진 파일을 포함한 모든 파일을 상위 디렉토리로 이동하는 방법 (0) | 2020.08.18 |
---|---|
C # 4 기본 매개 변수 값 : 기본 DateTime / 개체 값을 할당하는 방법은 무엇입니까? (0) | 2020.08.18 |
자동 레이아웃 제약 조건을 사용할 때 뷰의 현재 너비와 높이를 어떻게 얻을 수 있습니까? (0) | 2020.08.18 |
express는`body-parser deprecated undefined extended`로 오류를 발생시킵니다. (0) | 2020.08.18 |
올바른 형식으로 JSON 파일에 쓰는 방법 (0) | 2020.08.18 |