分析完了服务器端,我们继续分析客户端,在socket编程中,客户端的流程是比较简单的,申请一个socket,然后调connect去发起连接就行。我们先看一下connect函数的定义。
/*
socket 通过socket函数申请的结构体
address 需要连接的目的地地址信息
*/
int connect(int socket, const struct sockaddr *address,socklen_t address_len);
我们通过层层调用揭开connect的迷雾。
static int sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
{
struct socket *sock;
struct file *file;
int i;
char address[MAX_SOCK_ADDR];
int err;
if (fd < 0 || fd >= NR_OPEN || (file=current->files->fd[fd]) == NULL)
return(-EBADF);
if (!(sock = sockfd_lookup(fd, &file)))
return(-ENOTSOCK);
i = sock->ops->connect(sock, (struct sockaddr *)address, addrlen, file->f_flags);
if (i < 0)
{
return(i);
}
return(0);
}
没有太多逻辑,通过fd找到关联的socket结构体。然后调底层函数。底层的函数是inet_connect,这个函数逻辑比较多,我们分开分析。