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;}
阅读全文
1 0
- socket编程(三)
- socket编程(三)
- socket编程(三)
- Java Socket编程(三)
- Java Socket编程(三)
- Java socket编程(三)
- Java(三) Socket编程
- socket 编程基础(三)
- linux socket 编程(三)
- Socket 基础编程(三)
- socket编程入门(三)
- Java Socket编程(三)服务器Sockets
- Java Socket编程(三) 服务器Sockets
- python Socket编程(三)----SMTP POP3
- java网络编程(三)socket
- Android中的socket编程(三)
- Socket网络编程笔记(三)
- Linux下Socket编程学习(三)
- android 放置so包的文件位置
- 网易云课堂《软件工程(C编码实践篇)》学习心得
- 操作系统之处理机调度
- servlet、filter、listener
- Eclipse安装配置教程
- socket编程(三)
- HBase 性能优化方法总结(一):表的设计
- Android查看api源码
- 51nod 1327 棋盘游戏
- java中的泛型
- iOS 修改导航栏上返回按钮上的文字,例如把 back 修改为 返回
- day02
- 上传文件错误
- 守护进程