reuseaddr和点对点聊天

解决绑定失败

在测试时,经常会出现绑定错误,bind error: Address already in use
这里只要指定一下socket的reuseaddr属性即可解决

int on=1;
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on) <0)
    err_quit("setsockopt");

bind(...)

点对点

1.本例子使用双进程,一个用于接受信息,一个用于发送消息
2.当read(sockfd)0或read(connfd)0时,需要两个进程都退出,此处用SIGUSR1作为通知信号

client.c

#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
 
void err_quit(const char *s){
    perror(s);
    exit(1);
}
 
void handler(int signo){
    printf("program terminated\n");
    exit(0);
}
 
int main(int argc,char *argv[]){
    int sockfd;
    struct sockaddr_in servaddr;
    char buff[1024];
    pid_t child;
 
    if((sockfd=socket(PF_INET,SOCK_STREAM,0)) < 0)
        err_quit("socket");
 
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    servaddr.sin_port=htons(5566);
 
    if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) <0)
        err_quit("connect");
 
    if((child=fork()) <0)
        err_quit("fork");
    else if(child == 0){
        signal(SIGUSR1,handler);
        while(fgets(buff,sizeof(buff),stdin) != NULL)
            write(sockfd,buff,strlen(buff));
    }else{
        while(1){
            memset(buff,0,sizeof(buff));
            int nread=read(sockfd,buff,sizeof(buff));
            if(nread == -1)
                err_quit("read");
            if(nread == 0){
               printf("perr closed\n");
               break;
            }
            fputs(buff,stdout);
        }
        kill(child,SIGUSR1);
    }
    exit(0);
}

server.c

#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
 
void err_quit(const char *s){
    perror(s);
    exit(1);
}
 
void handler(int signo){
    printf("program terminated\n");
    exit(0);
}
 
int main(int argc,char *argv[]){
    int sockfd,connfd;
    pid_t child;
    socklen_t len;
    struct sockaddr_in addr,client;
    char buff[1024];
 
    if((sockfd=socket(PF_INET,SOCK_STREAM,0)) < 0)
        err_quit("sockfd");
 
    bzero(&addr,sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr=htonl(INADDR_ANY);
    addr.sin_port=htons(5566);
 
    int on=1;
    if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) <0)
        err_quit("setsockopt");
 
    if(bind(sockfd,(struct sockaddr *)&addr,sizeof(addr))<0)
        err_quit("bind");
 
    if(listen(sockfd,10)<0)
        err_quit("listen");
 
    len=sizeof(client);
    connfd=accept(sockfd,(struct sockaddr *)&client,&len);
    if(connfd < 0)
        err_quit("accept");
 
    if((child=fork())<0){
        err_quit("fork");
    }else if(child  == 0){
        while(1){
            bzero(buff,sizeof(buff));
            int nread=read(connfd,buff,1024);
            if(nread == -1)
                err_quit("read");
            if(nread == 0){
                printf("peer closed\n");
                break;
            }
            fputs(buff,stdout);
        }
        kill(getppid(),SIGUSR1);
    }else{
        signal(SIGUSR1,handler);
        while(fgets(buff,sizeof(buff),stdin) != NULL){
            write(connfd,buff,strlen(buff));
        }
    }
    exit(0);
}
posted @ 2016-12-04 21:15  cfans1993  阅读(164)  评论(0编辑  收藏  举报