Socket相信大家只要是跟网络有关的都用过,有了Socket我们不必关心底层的三次握手,四次挥手等,我们只需要将几个基本步骤利用linux内置的函数绑定,传递,关闭即可。Linux的哲学就是,一切都是“文件”,Socket在其中也是如此,它是一个特殊的文件,我们能打开,读写,关闭这个特殊的文件句柄来实现我们通信的目的(其实说白了描述符就是一个整数,如下图1所示,我们调用创建返回的Socket实际上是一个索引值,文件描述表的索引)。
大致的步骤我就不说了,网上随处可见,在这里引用别人的一个图2,服务器端需要进行socket(),bind(),listen(),accept(),阻塞得等待客户端的连接,客户端需要socket(),connect(),在这里,bind()主要是绑定对应IP和端口(一般是众所周知的端口),listen()来监听此端口。注意!此时服务器第一个创建的listen_fd=socket()句柄listen_fd专门为了监听所用,在客户端请求连接connect()成功,服务器data_fd= accept()成功后,data_fd才是后来进行数据传递所需要的句柄,此处不要弄混,之后服务器向客户端读写read(),write()都用的是data_fd,而不是listen_fd。当然客户端只有一个句柄,故不会有混淆处。
客户端一般不需要bind(),在connect()时这个函数会为客户端自动分配一个空闲的端口来进行通讯,当然我们说的是不需要也不必,如果你非要客户端指定端口去通信,也是可以的,C代码如下所示。
struct sockaddr_in client_addr;//自己指定端口,一般不这样做,connect会自动分配的
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr=htonl(INADDR_ANY);
client_addr.sin_port = htons(2001);
if (bind(socket_fd, (SA *)&client_addr,sizeof(client_addr)) == -1){
printf("binderror!");
return0;
}
图1
图2