TCP服务器和客户端的链接例子(侧重点在注意关闭套接子,减少套接子的描述子)

  TCP服务器和客户端的链接例子(侧重点在注意关闭套接子,减少套接子的描述子)
每个文件或套接口都有一个访问计数,该访问计数在文件表项中维护,它表示当前指向该文件或套接口的打开的描述字个数。

每个文件,套接口都有一个访问计数器,表示当前指向该文件或套接口的打开的描述子个数。从accpet返回后client_fd关联的文件表项访问计数值为1,从socket返回后,与sockfd的关联的文件表项访问计数值为1;但是,当fork返回后,两个描述子在父进程和子进程复制,所以,与两个套接口相关联的文件表项访问计数值均为2.当父进程关闭client_fd时,只是将访问计数值从2减少为1。描述字在访问记数值为0时才真正关闭。
如果父进程从未关闭accpet返回的已经链接套接口调用close。父进程最终将耗尽可用描述子,因为任何进程在某个时刻打开的描述子数是有限的。更重要的是没有一个客户链接被终止。如果父进程从未关闭已经链接套接口,这将防挨TCP链接终止序列的执行,从而链接永远保持开发。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
#define MAXDATASIZE 100
#define SERVPORT 3333 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */
int main()
{
        pid_t pid;
        char line[100];
        ssize_t n;
        int recvbytes,nfds,i,epfd;
        char buf[100];
        char ref[100];
        int sockfd,client_fd; /*sock_fd:监听socket;client_fd:数据传输socket */
        int sockfds;
        //声明epoll_event结构体变量,ev用于注册事件,数组用于回传要处理的事件
        //epoll_event被用于注册所感兴趣的事件和回传所发生的待处理事件
        struct epoll_event ev,events[20];
        epfd = epoll_create(256);//256这个参数可以改变(网上看到过有设为5000)
       
        struct sockaddr_in my_addr; /* 本机地址信息 */
        struct sockaddr_in remote_addr; /* 客户端地址信息 */
        socklen_t sin_size;
        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                perror("socket创建出错!"); exit(1);
        }

        my_addr.sin_family=AF_INET;
        my_addr.sin_port=htons(SERVPORT);
        my_addr.sin_addr.s_addr = INADDR_ANY;
        bzero(&(my_addr.sin_zero),8);
        if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
                perror("bind出错!");
                exit(1);
        }
        if (listen(sockfd, BACKLOG) == -1) //BACKLOG有最大数值限制,超过这个数值时出现ECONNREFUSEd错误
        {
                perror("listen出错!");
                exit(1);
        }
        while(1)
        {
                sin_size = sizeof(struct sockaddr_in);
                if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1)
                {
                        perror("accept出错");
                        exit(0);
                        //continue;
                }
                if((pid=fork())==0)
                {
                        close(sockfd);
                        printf("1: client_fd: %d; sockfd: %d\n",client_fd,sockfd);
                        bzero(buf,100);
                        strcpy(buf,"Client has connected Server!");
                        strcat(buf,"\n");
                        if(-1==send(client_fd,buf,100,0))
                        {
                                printf("Err:send failed <%s> %s\n",buf,strerror(errno));
                                exit(1);
                        }
                        //close(client_fd);
                        exit(0);

                }
                close(client_fd);
                waitpid(-1,NULL,WNOHANG);

                printf("2: client_fd: %d; sockfd: %d\n",client_fd,sockfd);                
        }

}

#include<stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#define SERVPORT 3333
#define MAXDATASIZE 100 /*每次最大数据传输量 */
int main(int argc, char *argv[])
{
        int sockfd, recvbytes;
        char buf[MAXDATASIZE];
        struct hostent *host;
        struct sockaddr_in serv_addr;
        char * argvs = "5000790-1";
        if((host=gethostbyname(argvs))==NULL)
        {
                herror("gethostbyname出错!");
                exit(1);
        }
        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)        
        {
                perror("socket创建出错!");
                exit(1);
        }
        serv_addr.sin_family=AF_INET;
        serv_addr.sin_port=htons(SERVPORT);
        serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
        bzero(&(serv_addr.sin_zero),8);
        if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1)
        {
                perror("connect出错!");
                exit(1);
        }

        for(int i=0; i<1; i++)
        {
                printf("%d client is ready to recv buf! \n",i);
                if ((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1)
                {
                        perror("recv出错!");
                        exit(1);
                }
                buf[recvbytes] = '\0';
                printf("%d Received: %s\n",i,buf);
                memset(buf,0,100);
        }      
        close(sockfd);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值