if(-1==sockfd=socket(AF_INET,SOCK_STREAM,0)){
perror("socket error");
exit(-1);
}//创建套接字文件,套接字的本质是用来标定系统为当前进程划分的一块缓冲空间!
//收发数据,都是通过网口,网口在发送到套接字中的(或者是套接字发给网口等),然后网口在发送给其他进程
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=inet_addr(argv[1]);
server_addr.sin_port=htons(atoi(argv[2]));//填充服务器网络信息结构体
socklen_t server_addr_len=sizeof(server_addr);
struct sockaddr_in client_addr;
socklen_t client_addr_len=sizeof(client_addr);
if(-1==bind(sockfd,(struct sockaddr*)&server_addr,server_addr_len)){
perror("bind error");
exit(-1);
}//将套接字和服务器网络信息结构体绑定,
//这样,流经该 IP 地址和端口的数据才能交给套接字处理,或者是进程要传输的信息才能通过套接字发送给网口!!!!!
if(listen(sockfd,5)==-1){
perror("listen error");
exit(-1);
}/*将套接字设置为监听状态,进入监听状态的套接字,当没有客户端请求时
套接字处于睡眠状态(但不是阻塞状态后面的代码依然会执行)
,只有接收到客户端请求时,套接字才会被唤醒来响应请求*/
signal(SIGCHLD, handler);//处理僵尸进程
while(1){
if(-1==acceptfd=accept(sockfd,(struct sockaddr*)&client_addr,&client_addr_len)){
perror("accept error");
exit(-1);
}/*accept是连接套接字,后面的两个储的accept的网络信息结构体(ip和端口号)
和accept网络信息结构体的大小,并不是通过保存了信息而进行传输信息的.
其次accept函数会阻塞(就是说运行到这个函数,如果没有客户端访问的情况下,后面的程序不会执行,跟listen不一样)
if(-1 == connect(socketfd, (struct sockaddr *)&server_addr, sizeof(server_addr))){
perror("fail to connect");
exit(-1);
}//该函数的功能是为客户端主动链接服务器
//调用connect函数将激发TCP的三次握手过程,而且仅在连接建立成功或出错时才返回。
//与服务器用connect链接之后才能向