#include"proto.h"
#include<string.h>
#define IPSTRSIZE 40
#define BUFSIZE 1024
typedef long long ll;
static void server_job(int sd){
int len;
char buf[BUFSIZE];
len=sprintf(buf,FMT_STAMP,(ll)time(NULL));
send(sd,buf,len,0);
}
int main(){
int sd;
char ipstr[IPSTRSIZE];
struct sockaddr_in laddr,raddr;//local address
socklen_t raddr_len;
sd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //参数三选择0代表根据前两个参数进行套接字使用的协议的自己确定 参数三:IPPROTO_TCP IPPROTO_UDP 0 包括还有其他协议
int val=1;
setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof val); //解决端口被占用的问题
laddr.sin_family=AF_INET; // 协议族
laddr.sin_port=htons(atoi(SERVERPORT)); //字符串转换为整形 IP和端口信息都会上传到网络上 端口
inet_pton(AF_INET,"0.0.0.0",&laddr.sin_addr);//any address 服务器将监听所有可用的网络接口 IP
bind(sd,(void*)&laddr,sizeof laddr);
if(listen(sd,200)<0) //listen 参数2:存放待处理请求的队列的最大长度
exit(1);
int new_sd;
pid_t pid;
raddr_len=sizeof raddr;
while(1){
new_sd=accept(sd,(void*)&raddr,&raddr_len);
if(new_sd<0)
{
// if(error==)
perror("accept()");
exit(1);
}
pid=fork();
if(pid==0){
//new_sd,sd 是父子进程都各有一个 子进程不需要sd 关闭
// close(sd);
inet_ntop(AF_INET,&raddr.sin_addr,ipstr,IPSTRSIZE);
printf("Client:%s:%d\n",ipstr,ntohs(raddr.sin_port));
server_job(new_sd);
exit(0);
}
close(new_sd);//不关闭不用的new_sd就会导致竞态 这里实在不懂就这么理解:在任何时候都记住释放不用的资源,因为文件描述符的不释放就相当于资源泄露。 close the new_sd of father
}
close(sd);
exit(0);
}
这里不删除父进程的new_id会导致子进程在调用server_job的send的时候出现未知问题,应该是静态,因为两个文件描述符是一样的,导致消息发不出去,在S端进行强制信号发送后,父进程结束,关闭掉自己的new_sd,所以此时子进程才得以继续执行,发送消息成功。不然就是一直阻塞。