tcp的超时时间设置
D:\011-Applying\Linux网络编程\源码-写博客
原始玩具
#include <unistd.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <strings.h>//bzero'h
#define SERV_IP "127.0.0.1"
#define SERV_PORT 6666
#include "wrap.h"
int main()
{
int sfd,cfd;
struct sockaddr_in serv_addr,clie_addr;
socklen_t clie_addr_len,client_IP_len;
char buf[BUFSIZ],cli_IP[BUFSIZ];
int i,n;
sfd = Socket(AF_INET,SOCK_STREAM,0);
bzero(&serv_addr,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
Bind(sfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
Listen(sfd,128);
clie_addr_len = sizeof(clie_addr);
cfd = Accept(sfd,(struct sockaddr*)&clie_addr,&clie_addr_len);
while(1)
{
n = Read(cfd,buf,sizeof(buf));
for(i= 0;i<n;i++)
buf[i] = toupper(buf[i]);
Write(cfd,buf,n);
}
close(sfd);
close(cfd);
return 0;
}
epoll玩具
#include <stdio.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>//bzero'h
#include <time.h>
#include "wrap.h"
#include <sys/wait.h>
#define SERV_IP "127.0.0.1"
#define SERV_PORT 6666
#define MAXLINE 8192
#define OPEN_MAX 5000
int main()
{
int i,listenfd,connfd,sockfd;
struct sockaddr_in serv_addr,clie_addr;
int n,num = 0;
ssize_t nready,efd,res;
char buf[MAXLINE],str[INET_ADDRSTRLEN];
socklen_t clilen;
struct sockaddr_in cliaddr,servaddr;
struct epoll_event tep,ep[OPEN_MAX];// tep:epoll_ctl 参数,ep[]:epoll_wait 参数
listenfd = Socket(AF_INET,SOCK_STREAM,0);
int opt = 1;
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); //端口复用
bzero(&serv_addr,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);//也可以写成inet_ntop(AF_INET,'127.0.0.1',&serv_addr.sin_addr.s_addr);
Bind(listenfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
Listen(listenfd,128);//同时与服务器发起三次握手的数量上限,最大是128,超过128也没有用,操作系统限定
printf("wait for client connect...\n");
efd = epoll_create(10); //创建epoll模型,efd指向红黑树根节点
if(efd == -1)
perr_exit("epoll_create error");
tep.events = EPOLLIN;
tep.data.fd = listenfd; // 指定lfd的监听事件是读事件
printf("成功创建epoll.\n");
res = epoll_ctl(efd,EPOLL_CTL_ADD,listenfd,&tep); //将lfd及对应的结构体设置到树上,efd可以找到该树
for(;;)
{
/*epoll为阻塞监听事件,ep为struct epoo_event类型数组,OPEN_MAX为数组容量,-1表示永久阻塞*/
printf("epoll_wait.\n");
nready = epoll_wait(efd,ep,OPEN_MAX,-1);
printf("nready is %d.\n",nready);
if(nready == -1)
perr_exit("epoll_wait error");
for(i = 0;i<nready;i++)
{
if(!(ep[i].events & EPOLLIN))
continue;//如果不是读事件,继续循环
if(ep[i].data.fd == listenfd)//判断满足事件的fd是不是lfd(listen fd)
{
clilen = sizeof(cliaddr);
connfd = Accept(listenfd,(struct sockaddr*)&cliaddr,&clilen);//接受连接
printf("client-IP:%s,client port:%d.\n",inet_ntop(AF_INET,&clie_addr.sin_addr.s_addr,str,sizeof(str)),ntohs(clie_addr.sin_port));
printf("cfd is %d,client is %d.\n",connfd,++num);
tep.events = EPOLLIN;
tep.data.fd = connfd;
res = epoll_ctl(efd,EPOLL_CTL_ADD,connfd,&tep);
if(res == -1)
perr_exit("epoll_ctl error");
}
else //不是listenfd
{
sockfd = ep[i].data.fd;
n = Read(sockfd,buf,MAXLINE);
if(n == 0)//读到0,说明客户端关闭连接,将该文件描述符从红黑树摘除
{
res = epoll_ctl(efd,EPOLL_CTL_DEL,connfd,NULL);
if(res == -1)
perr_exit("epoll_ctl error");
Close(sockfd);
printf("client [%d] closed connection.\n",sockfd);
}
else if(n<0) // 出错
{
perror("read n < 0 error:");
res = epoll_ctl(efd,EPOLL_CTL_DEL,connfd,NULL);
close(sockfd);
}
else //实际读到了字节数
{
for(i = 0;i<n;i++)
buf[i] = toupper(buf[i]);//转大写,写回给客户端
Write(STDOUT_FILENO,buf,n);
Writen(sockfd,buf,n);
}
}
}
}
Close(listenfd);
Close(efd);
return 0;
}