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