TPC并发服务器
用进程
1.创建套接字socket
2.绑定套接字信息bind
3.监听队列listen
4.等待连接accept
void func(int arg) { wait(NULL); } signal(17,func) while(1) { confd=accept(); fork(); if(pid==0) { signal(17,func) fork(); if(pid==0) { while(1) { fgets(); write(); } } while(1) { read(); } } }
用线程
1.创建套件字socket
2.绑定套件字信息bind
3.监听队列listen
4.等待连接accept
传入的参数confd一定要转化为int类型!!!
void *fun1(void*arg) { while(1) { read; } } void *fun2(void*arg) { while(1) { write; } } socklen_t len=sizeof(addr); while(1) { confd=accept(sockfd,(struct sockaddr*)&addr,&len); pthread_create(tid1); pthread_create(tid2); pthread_detach(tid1); pthread_detach(tid2); }
客户端:
1.创建套接字socket
2.创建结构体选择发送的服务器的信息
3.连接connect();
4.发送信息
while(1) { read(sockfd); write(sockfd); }
UDP单播
服务器:
1.创建套接字socket
2.绑定套接字信息bind
struct sockaddr_in con; socklen_t len=sizeof(con) while(1) { recvfrom(sockfd,buf,sizeof(buf),0,(struct sockddr)&con,&len);//仅接收信息可以不用存储客户端网络信息。如果想发送回去需要提前保存客户端的网络信息。 sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&addr,sizeof(addr)); }
套接字分类 1.流式套接字 2.报式套接字 3.unix域套接字 只能进行本机通信
unix通信:
1.创建套接字socket
2.接收端绑定信息
struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ char sun_path[108]; /* Pathname */ }; 作用:传递文件描述符,传递凭证 }
3.通信
ip地址分类
A:一个字节为网络号,3个字节为主机号 学校,国企 以0开始 范围 0.0.0.0到127.255.255.255 0.0.0.0 本机 127.0.0.1回环 以.255结尾广播地址 B:两个字节为网络号,2个字节为主机号 私有 以10开始 范围128.0.0.0 到 191.255.255.255 C:三个字节为网络号,1个字节为主机地址 私有 以110开始 范围192.0.0.0 到 223.255.255.255 D:组播地址 以1110开始 范围224.0.0.0 到239.255.255.255 E:保留地址 以11110开始
UDP广播
广播 向广播地址发送消息 发送广播 1.设置允许发送广播选项 setsockopt() 2.向广播地址发送信息 以255结尾
接收广播 1.绑定的地址需要是一个广播地址或者是0地址
接收端:
1.创建套接字socket
2.绑定套接字信息bind
3.接收数据
发送端
1.创建套接字socket
2.设置允许广播setsockopt()
3.向广播地址.255结尾的地址发送数据
组播
加入组播地址才能收到发给组播地址的信息 • struct ip_mreq • struct in_addr imr_multiaddr; //组播地址 • struct in_addr imr_interface; //加入到组播组中的地址 • 发送组播{ • 1.创建套接字socket 2.创建组播结构体 struct ip_mreq m; struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(6666); addr.sin_addr.s_addr = inet_addr("239.2.2.2"); m.imr_multiaddr.s_addr=inet_addr("239.2.2.2");//组播地址 m.imr_interface.s_addr=inet_addr("192.168.7.95")//加入组播的地址 • 3.允许发送组播地址setsockopt() 4.sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&m,sizeof(m)) //向这个组播地址发送数据 • 接收方{ • 1.创建套接字socket struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(6666); addr.sin_addr.s_addr = inet_addr("239.2.2.2");//与这个组播地址绑定接收这个组播的数据 • 2.绑定bind • 3.加入到组播组中setsockopt() m.imr_multiaddr.s_addr=inet_addr("239.2.2.2");//组播地址 m.imr_interface.s_addr=inet_addr("192.168.7.95")//加入组播的地址
超时检测:
1.使用io多路复用设置超时检查
select,poll,epoll超时返回0
2.信号unsigned int alarm(unsigned int seconds);
用signal捕捉alarm闹钟信号模拟超时
3.设置套接字属性 int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
socklen_t len=sizeof(con); struct timeval timeout={4,0}; setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,&timeout,sizeof(timeout)); while(1) { int confd=accept(sockfd,(struct sockaddr*)&addr,&len); if(-1==confd) { if(errno==11) { printf("time out\n"); } else { perror("accept"); return -1;
功能:设置套接字属性
返回值:成功返回0,失败-1
参数:sockfd:套接字文件描述符 level:设置的协议是哪一层的 optname:具体指令 optval:根据不同指令传递的值 optlen:结构体大小
设置属性表:level • SOL_SOCKET --------------------------------------------------- • 参数optname 宏的作用 对应参数optval的类型 • • SO_BROADCAST 允许发送广播数据 int • SO_DEBUG 循序调试 int • SO_DONTROUTE 不查找路由 int • SO_ERROR 获的套接字错误 int • SO_KEEPALIVE 保持连接 int • SO_LINGER 延迟关闭连接 struct linger • SO_OOBINLINE 带外数据放入正常数据流 int • SO_RCVBUF 接收缓冲区大小 int • SO_SNDBUF 发送缓冲区大小 int • SO_RCVLOWAT 接收缓冲区下限 int • SO_SNDWAIT 发送缓冲区下限 int • SO_RCVTIMEO 接收超时 struct timeval • SO_SNDTIMEO 发送超时 struct timeval • SO_REUSEADDR 允许重用本机地址和端口 int • SO_TYPE 获得套接字类型 int • SO_BSDCOMPAT 与BSD系统兼容 int • =================================================== • • IPPROTO_IP ------------------------------------------------------ • IP_ADD_MEMBERSHIP 加入到组播组中 struct ip_mreq • IP_MULTICAST_IF 允许开启组播报文的接口 struct ip_mreq