其他分享
首页 > 其他分享> > accept函数

accept函数

作者:互联网

#include <sys/socket.h>

int accept(int sockfd,struct sockaddr *cliaddr,socklen_t *addrlen);

                    返回:若成功返回非负描述符,若出错则返回-1

  参数cliaddr和addrlen用来返回已连接的对端(客户)进程的协议地址。addrlen是值-结果参数:调用前,将由*addrlen所引用的整数值置为由cliaddr所指的套接字地址结构的长度,返回时,该整数值即为有内核放在该套接字地址结构内的确切字节数。

  accept调用成功,返回一个全新的描述符,代表所返回客户的TCP连接。在讨论accept函数时,称第一个参数为监听套接字描述符,它的返回值为已连接套接字描述符。服务器通常仅仅创建一个监听套接字,它在该服务器的生命周期内一直存在。内核为每个服务器进程接受的客户连接创建一个已连接套接字。当服务器完成对某个给定客户的服务时,相应的已连接套接字就关闭。

 

  下列服务器程序的代码中定义了len它将成为一个值-结果变量,cliaddr,它将存放客户的协议地址

/*unix.h 头文件*/
#include <errno.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <signal.h> #include <pthread.h> #include <sys/types.h> #include "fun.c" #define MAXLINE 124 #define SERV_PORT 5555 #define ip "127.0.0.1"
/*fun.c  函数c文件,目的是避免错误处理写在客户/服务器程序上,看起来缭乱,不易阅读*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define MAXLINE 124
void err_sys(char *str)
{
    printf("%s\n",str);
    exit(1);
}
int Inet_pton(int domain,const char * str,void *addr)
{
    int fg;
    if((fg=inet_pton(domain,str,addr))==-1)
        err_sys("inet_pton error");
    return fg;
}
int Socket(int family,int type,int protocol)
{
    int  n;
    if((n=socket(family,type,protocol))<0)
        err_sys("socket error");
    return n;
}

void Bind(int sockfd,struct sockaddr_in *addr,socklen_t len)
{
    if(bind(sockfd,(struct sockaddr*)addr,len)==-1)
        err_sys("bind error");
}
void Connect(int sockfd,struct sockaddr_in *addr,socklen_t len)
{
    if(connect(sockfd,(struct sockaddr*)addr,len)==-1)
        err_sys("connect error");
}

void Listen(int fd,int bocklog)
{
    if(listen(fd,bocklog)==-1)
        err_sys("listen error");
}
int Accept(int sockfd,struct sockaddr_in *addr,socklen_t *len)
{
    int fd=accept(sockfd,(struct sockaddr*)addr,len);
    if(fd==-1)
        err_sys("accept error");
    return fd;
}
ssize_t Read(int fd,void *buf,size_t nbytes)
{
    int n;
    if((n=read(fd,buf,nbytes))==-1)
        err_sys("read error");
    return n; 
}
ssize_t Write(int fd,const void *buf,size_t nbytes)
{
    int n;
    if((n=write(fd,buf,nbytes))==-1)
        err_sys("write error");
    return n;
}

void str_echo(int sockfd)
{
    ssize_t n;
    char buf[MAXLINE];
again:
    while((n=read(sockfd,buf,MAXLINE))>0)
        Write(sockfd,buf,n);
    if(n < 0 && errno==EINTR)
        goto again;
    else if(n<0)
        err_sys("str_echo:read error");
}

char *Fgets(char *buf,int size,FILE *stream)
{
    if(fgets(buf,size,stream)==NULL)
        return NULL;
    return buf;
}
void Fputs(char *buf,FILE *stream)
{
    if(fputs(buf,stream)==-1)
        err_sys("fputs error");        
}
void str_cli(FILE *fp,int sockfd)
{
    char sendline[MAXLINE],recvline[MAXLINE];
    while(Fgets(sendline,MAXLINE,fp)!=NULL)
    {
        Write(sockfd,sendline,strlen(sendline));
        if(Read(sockfd,recvline,MAXLINE)==0)
            err_sys("str_cli:server terminated prematurely");
        Fputs(recvline,stdout);
    }
}
/*服务器程序*/
#include "unix.h" char buf[124]; int main() { int serv_fd,cli_fd; pid_t pro_cli; struct sockaddr_in serv_addr; serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(SERV_PORT); //Inet_pton(AF_INET,ip,&serv_addr.sin_addr.s_addr); serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); serv_fd=Socket(AF_INET,SOCK_STREAM,0); Bind(serv_fd,&serv_addr,sizeof(serv_addr)); Listen(serv_fd,9); struct sockaddr_in cliaddr; socklen_t len=sizeof(cliaddr); while(1) { cli_fd=Accept(serv_fd,&cliaddr,&len); if((pro_cli=fork())==-1) printf("fork error"); else if(pro_cli==0) { str_echo(cli_fd); close(cli_fd); } } return 0; }
/*客户端代码*/
#include "unix.h" char buf[124]; int main() { int fd; struct sockaddr_in addr; addr.sin_family=AF_INET; addr.sin_port=htons(SERV_PORT); Inet_pton(AF_INET,ip,&addr.sin_addr.s_addr); fd=Socket(AF_INET,SOCK_STREAM,0); Connect(fd,&addr,sizeof(addr)); fgets(buf,sizeof(buf),stdin); Write(fd,buf,13); exit(0); }

 

服务器运行:

客户连接服务器,服务器把客户发送的字符串回射给客户,并输出

(回射代码部分有问题,所以出现了?的那一行)

 

 

 

  

标签:serv,函数,int,accept,fd,include,sin,addr
来源: https://www.cnblogs.com/hei-dashuai/p/16552173.html