首先我们来说用到的函数
socket
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain,int type,int protocol);
*socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符;
*应用程序可以像读写文件一样用read/write在网络上收发数据;
*如果socket()调用出错则返回-1;
*对于IPv4,family参数指定为AF_INET(第一个参数);
*对于TCP协议,type参数指定为SOCK_STREAM,面向字节流的传输协议(第二个参数)
*protocol指定为0就可以了(第三个参数)
bind
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接;服务器需要调用bind绑定一个固定的网络地址和端口号
bind成功返回0。失败返回-1
bind的作用是将参数sockfd和myaddr绑定在一起,使sockfd这个用于网络通讯的文件描述符监听myaddr所描述的地址和端口号;
前面讲过,struct sockaddr*是一个通用指针类型,myaddr参数实际上可以接受多种协议的sockaddr结构体,而他们的长度各不一样,所以需要第三个参数addrlen指定结构体的长度;
我们程序中堆myaddr参数是这样初始化的:
bzero(&servaddr,sizeof(servaddr);
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
1:将整个结构体清零;
2:设置地址类型为AF_INET;
3:网络地址为INADDR_ANY,这个宏可以表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也可能绑定多个IP地址,这个设置可以在所有的IP地址上监听,知道与某个客户端建立了连接时才确定下来到底用哪个IP地址;
4:端口号为SERV_PORT,我们定义为9999
listen
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd,int backlog);
listen()声明sockfd处于监听状态,并且最多允许有backlog个客户短处与连接等待状态,如果接受到更多的连接请求就忽略,这里设置不会太大(一般是5)
listen()成功返回0;失败返回-1;