套接字连接()与绑定()

connect()bind()系统调用将套接字文件描述符“关联”到一个地址(通常是一个ip / port组合)。 他们的原型是这样的:

 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()用于连接到远程[server]地址,这就是为什么客户端,使用连接[读为:连接到服务器]。

由于具体的angular色和相应的实现,我们不能交替使用它们(即使我们在同一台机器上有客户端/服务器)。

我将进一步build议关联这些调用TCP / IP握手。

在这里输入图像说明

那么,谁会在这里发送SYN,这将是connect()。 bind()用于定义通信终点。

希望这可以帮助!!

一行: bind()到自己的地址, connect()到远程地址。

bind()的手册页引用

bind()将由addr指定的地址分配给由文件描述符sockfd引用的套接字。 addrlen指定addr指向的地址结构的大小(以字节为单位)。 传统上,这个操作被称为“给套接字分配一个名字”。

connect()相同,

connect()系统调用将由文件描述符sockfd引用的套接字连接到由addr指定的地址。

澄清,

  • bind()将套接字与本地地址相关联[这就是服务器端bind的原因,以便客户端可以使用该地址连接到服务器。]
  • connect()用于连接到远程[服务器]地址,这就是为什么客户端,使用连接[读为:连接到服务器]。

从维基百科http://en.wikipedia.org/wiki/Berkeley_sockets#bind.28.29

连接():

connect()系统调用将由其文件描述符标识的套接字连接到参数列表中由该主机地址指定的远程主机。

某些types的套接字是无连接的,最常见的是用户数据报协议套接字。 对于这些套接字,连接具有特殊含义:发送和接收数据的默认目标设置为给定地址,允许在无连接套接字上使用send()和recv()等函数。

connect()返回一个表示错误代码的整数:0代表成功,-1代表错误。

绑定():

bind()将套接字分配给一个地址。 当使用socket()创build一个套接字时,它只被赋予一个协议族,但没有分配一个地址。 这个与地址的关联必须在套接字可以接受到其他主机的连接之前用bind()系统调用来执行。 bind()有三个参数:

sockfd,一个描述符,代表套接字执行绑定。 my_addr,指向表示要绑定的地址的sockaddr结构的指针。 addrlen,一个指定sockaddr结构大小的socklen_t字段。 Bind()在成功时返回0,如果发生错误则返回-1。

例子:1)使用连接

 #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, ie 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); } 

我希望澄清不同之处

编辑:请注意,你声明的套接字types将取决于你所需要的,这是非常重要的

绑定告诉正在运行的进程要求一个端口。 即它应该将自己绑定到端口80并监听input请求。 绑定,你的过程成为一个服务器。 当您使用连接时,您告诉您的进程连接到已经使用的端口。 你的过程成为客户。 区别很重要:绑定想要一个未被使用的端口(以便它可以声明它并成为一个服务器),并且connect想要一个已经被使用的端口(所以它可以连接到它并与服务器交谈)