#include <csapp.h>
int open_clientfdd(char *hostname,char *port);
int open_listenfdd(char *port);
void echo(int connfd);
int main(int argc,char **argv) {
int listenfd, connfd;
socklen_t clientlen;
struct sockaddr_storage clientaddr;
char client_hostname[MAXLINE],client_port[MAXLINE];
if(argc != 2){
fprintf(stderr,"usage:%s <port> \n",argv[0]);
exit(0);
}
listenfd = open_listenfdd(argv[1]);
while(1){
clientlen = sizeof(struct sockaddr_storage);
connfd = accept(listenfd,(SA *)&clientaddr,&clientlen);
getnameinfo((SA *)&clientaddr,clientlen,client_hostname,
MAXLINE,client_port,MAXLINE,0);
printf("connected to (%s,%s)\n",client_hostname,client_port);
echo(connfd);
close(connfd);
}
exit(0);
}
int open_clientfdd(char *hostname,char *port){
int clientfd;
struct addrinfo hints,*listp,*p;
/* get a list of potential server address*/
memset(&hints,0,sizeof(struct addrinfo));
hints.ai_socktype = SOCK_STREAM; /* open a connection */
hints.ai_flags = AI_NUMERICSERV; /* use a numeric prot arg */
hints.ai_flags |= AI_ADDRCONFIG; /* recommended for connections */
getaddrinfo(hostname,port,&hints,&listp);
/* walk the list for one that we can successfully connect to.*/
for(p = listp ; p; p = p->ai_next){
/* create a socket descriptor */
if((clientfd = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) < 0){
continue;
}
/* connect to the server*/
if(connect(clientfd,p->ai_addr,p->ai_addrlen) != -1 ){
break; /* connect success */
}
close(clientfd);
}
/* clean up */
freeaddrinfo(listp);
if(!p) /* all connects failed */
return -1;
else
return clientfd;
}
int open_listenfdd(char *port){
struct addrinfo hints,*listp,*p;
int listenfd, optval = 1;
/* get a list of potential server address*/
memset(&hints,0,sizeof(struct addrinfo));
hints.ai_socktype = SOCK_STREAM; /* open a connection */
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; /* use a numeric prot arg */
hints.ai_flags |= AI_NUMERICSERV; /* recommended for connections */
getaddrinfo(NULL,port,&hints,&listp);
/* walk the list for one that we can bind to.*/
for(p = listp ; p; p = p->ai_next){
/* create a socket descriptor */
if((listenfd = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) < 0){
continue;
}
/* eliminates "address already in use" error from bind*/
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,
(const void *)&optval,sizeof(int));
/* bind the descriptor to the address */
if(bind(listenfd,p->ai_addr,p->ai_addrlen) == 0 ){
break; /* connect success */
}
close(listenfd); /* bind failed , try next*/
}
/* clean up */
freeaddrinfo(listp);
if(!p) /* no address worked */
return -1;
/* make it a listening socket ready to accept connection request*/
if(listen(listenfd,LISTENQ) < 0){
close(listenfd);
return -1;
}
return listenfd;
}
// echo fun
void echo(int connfd){
size_t n;
char buf[MAXLINE];
rio_t rio;
rio_readinitb(&rio,connfd);
while((n = rio_readlineb(&rio,buf,MAXLINE)) != 0){
printf("server received %d bytes\n",(int)n);
rio_writen(connfd,buf,n);
}
}
【c语言】实现打开一个连接描述符,并操作描述符
最新推荐文章于 2022-11-15 16:02:48 发布