socket编程(三)

来源:互联网 发布:java 日期格式化 编辑:程序博客网 时间:2024/06/08 04:09

1.REUSEADDR

服务器端尽可能使用REUSEADDR

在绑定之前尽可能调用setsockopt来设置REUSEADDR套接字选项。

使用REUSEADDR选项可以使得不必等待TIME_WAIT状态消失可以重启服务器。

2.处理多客户连接(process-per-connection)

echoserver.cpp

#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#define ERR_EXIT(m) \    do \    { \    perror(m); \    exit(EXIT_FAILURE); \    }while(0)    void do_service(int conn) {  char recvbuf[1024];  while(1) {  memset(recvbuf, 0, sizeof(recvbuf));  int ret = read(conn, recvbuf, sizeof(recvbuf));if(0 == ret) {  //server端知道client关闭printf("client close\n");break;} else if(-1 == ret) {ERR_EXIT("read");}  fputs(recvbuf, stdout);  write(conn, recvbuf, ret);  }}int main () {  int listenfd;if(( listenfd= socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)  //if((listenfd= socket(PF_INET, SOCK_STREAM, 0)) <0)   ERR_EXIT("socket");      struct sockaddr_in servaddr;  memset(&servaddr, 0, sizeof(servaddr));  servaddr.sin_family = AF_INET;  servaddr.sin_port = htons(5188);  //servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");  //inet_aton("127.0.0.1", &servaddr.sin_addr);  int on = 1;if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)ERR_EXIT("setsockopt");  if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))<0)  ERR_EXIT("bind");    if(listen(listenfd, SOMAXCONN) < 0)  ERR_EXIT("listen");    struct sockaddr_in peeraddr;  socklen_t peerlen = sizeof(peeraddr);  int conn;pid_t pid;while(1) {if((conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen)) < 0)ERR_EXIT("accept");printf("ip=%s port=%d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));pid = fork();if(-1 == pid) {ERR_EXIT("fork");}if(pid == 0) {  //child close(listenfd);do_service(conn);exit(EXIT_SUCCESS);} else {//parentclose(conn);}  }close(listenfd);close(conn);  return 0;}

echoclient.cpp

#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#define ERR_EXIT(m) \    do \    { \    perror(m); \    exit(EXIT_FAILURE); \    }while(0)    int main () {  int sock;if(( sock= socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)  ERR_EXIT("socket");    sock = socket(PF_INET, SOCK_STREAM, 0);    struct sockaddr_in servaddr;  memset(&servaddr, 0, sizeof(servaddr));  servaddr.sin_family = AF_INET;  servaddr.sin_port = htons(5188);  servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");    if(connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)  ERR_EXIT("connect");      char sendbuf[1024] = {0};  char recvbuf[1024] = {0};  while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL) {  write(sock, sendbuf, strlen(sendbuf));  memset(sendbuf, 0, sizeof(sendbuf));  memset(recvbuf, 0, sizeof(recvbuf));  int ret = read(sock, recvbuf, sizeof(recvbuf));  fputs(recvbuf, stdout);  }    close(sock);  return 0;}


3.点对点聊天程序实现

p2pserver.cpp

#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <signal.h>#define ERR_EXIT(m) \    do \    { \    perror(m); \    exit(EXIT_FAILURE); \    }while(0)    void handler(int sig) {printf("recv a sig=%d\n", sig);exit(EXIT_SUCCESS);}int main () {  int listenfd;if(( listenfd= socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)  //if((listenfd= socket(PF_INET, SOCK_STREAM, 0)) <0)   ERR_EXIT("socket");      struct sockaddr_in servaddr;  memset(&servaddr, 0, sizeof(servaddr));  servaddr.sin_family = AF_INET;  servaddr.sin_port = htons(5188);  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  //servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");  //inet_aton("127.0.0.1", &servaddr.sin_addr);  int on = 1;if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)ERR_EXIT("setsockopt");  if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))<0)  ERR_EXIT("bind");    if(listen(listenfd, SOMAXCONN) < 0)  ERR_EXIT("listen");    struct sockaddr_in peeraddr;  socklen_t peerlen = sizeof(peeraddr);  int conn;  if((conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen)) < 0)  ERR_EXIT("accept");printf("ip=%s port=%d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));  pid_t pid;pid = fork();if(-1 == pid) {ERR_EXIT("fork");}if(0 == pid) {signal(SIGUSR1, handler);char sendbuf[1024] = {0};while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL) {write(conn, sendbuf, strlen(sendbuf));memset(sendbuf, 0, sizeof(sendbuf));}printf("child close\n");close(listenfd);close(conn);//ERR_EXIT(EXIT_SUCCESS);} else {char recvbuf[1024];while(1) {memset(recvbuf, 0, sizeof(recvbuf));int ret = read(conn, recvbuf, sizeof(recvbuf));if(0 == ret) {printf("peer close\n");break;} else if(-1 == ret) {ERR_EXIT("read");}fputs(recvbuf, stdout);}printf("parent close\n");kill(pid, SIGUSR1);close(listenfd);close(conn);//ERR_EXIT(EXIT_SUCCESS);}  return 0;}

p2pclient.cpp

#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <signal.h>#define ERR_EXIT(m) \    do \    { \    perror(m); \    exit(EXIT_FAILURE); \    }while(0)    void handler(int sig) {printf("recv a sig=%d\n", sig);exit(EXIT_SUCCESS);}int main () {  int sock;if(( sock= socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)  ERR_EXIT("socket");    sock = socket(PF_INET, SOCK_STREAM, 0);    struct sockaddr_in servaddr;  memset(&servaddr, 0, sizeof(servaddr));  servaddr.sin_family = AF_INET;  servaddr.sin_port = htons(5188);  servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");    if(connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)  ERR_EXIT("connect");  pid_t pid;pid = fork();if(-1 == pid) {ERR_EXIT("fork");}if(0 == pid) {char recvbuf[1024] = {0};while(1) {memset(recvbuf, 0, sizeof(recvbuf));int ret = read(sock, recvbuf, sizeof(recvbuf));if(-1 == ret) {ERR_EXIT("read");} else if(0 == ret) {printf("peer close\n");break;}fputs(recvbuf, stdout);}close(sock);kill(getppid(), SIGUSR1);exit(EXIT_SUCCESS);} else {signal(SIGUSR1, handler);char sendbuf[1024] = {0};while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL) {write(sock, sendbuf, strlen(sendbuf));memset(sendbuf, 0, sizeof(sendbuf));}close(sock);exit(EXIT_SUCCESS);}      return 0;}


原创粉丝点击