赞
踩
服务器代码示例
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <sys/select.h> #include <sys/time.h> #define ERR_MSG(msg) do{\ fprintf(stderr, "__%d__:", __LINE__);\ perror(msg);\ }while(0) #define PORT 6666 #define IP "192.168.31.114" //本机IP:ifconfig查看 int updatemaxfd(int maxfd,fd_set readfds) { for(int j=maxfd;j>=0;j--) { if(FD_ISSET(j,&readfds)) { return j; } } return 0; } int main(int argc, const char *argv[]) { //创建流式套接字 int sfd = socket(AF_INET, SOCK_STREAM, 0); if(sfd < 0) { ERR_MSG("socket"); return -1; } //允许端口快速重用 int reuse = 1; if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { ERR_MSG("setsockopt"); return -1; } printf("允许端口快速重用设置成功\n"); //填充IP和端口到地址信息结构体中,实际结构体是由地址族决定: //AF_INET --> man 7 ip struct sockaddr_in sin; sin.sin_family = AF_INET; //地址族必须指定为AF_INET sin.sin_port = htons(PORT); //端口号的网络字节序:1024~49151 sin.sin_addr.s_addr = inet_addr(IP); //ubuntu的本机IP:ifconfig可以查看 //绑定服务器的IP地址和端口,必须绑定 if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("bind"); return -1; } printf("bind success\n"); //将套接字设置为被动监听状态 if(listen(sfd, 10) < 0) { ERR_MSG("listen"); return -1; } printf("listen success\n"); //创建读集合 fd_set readfds,tempfds; //清空集合 FD_ZERO(&readfds); FD_ZERO(&tempfds); //文件描述符放入读集合中 FD_SET(0,&readfds); FD_SET(sfd,&readfds); int maxfd = sfd; int st_res = 0; char buf[128] = ""; ssize_t res = 0; int newfd = 0; struct sockaddr_in cinarr[1020]; struct sockaddr_in cin ; //接收客户端的IP和端口 socklen_t addrlen = sizeof(cin); int i = 0; while(1) { tempfds = readfds; //调用select函数 st_res = select(maxfd+1,&tempfds,NULL,NULL,NULL); if(st_res < 0) { perror("select"); return -1; } else if(0 == st_res) { printf("time out\n"); break; } for(i=0;i<=maxfd;i++) { //判断i对应文件描述符是否在集合中 if(FD_ISSET(i,&tempfds) == 0) { continue; } if(0 == i) { printf("键盘输入\n"); bzero(buf,sizeof(buf)); fgets(buf,sizeof(buf),stdin); printf("buf = %s\n",buf); } else if(i ==sfd) { printf("客户端连接\n"); //获取新的文件描述符,该描述符用于通信、交互 newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen); if(newfd < 0) { ERR_MSG("accept"); return -1; } printf("[%s:%d] newfd = %d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd); //客户端地址信息结构体存入数组中 cinarr[newfd-4] = cin; //newfd添加进集合 FD_SET(newfd,&readfds); //更新maxfd maxfd = maxfd>newfd ? maxfd : newfd; } else { printf("客户端交互\n"); bzero(buf, sizeof(buf)); //接收 res = recv(i, buf, sizeof(buf), 0); if(res< 0) { ERR_MSG("recv"); return -1; } else if(0 == res) { fprintf(stderr, "[%s:%d] newfd = %d客户端关闭\n",inet_ntoa(cinarr[i-4].sin_addr),ntohs(cinarr[i-4].sin_port), i); close(i); //将不需要的文件描述符从集合中删除 FD_CLR(i,&readfds); //更新maxfd maxfd = updatemaxfd(maxfd,readfds); } else { printf("[%s:%d] newfd = %d:%s\n",inet_ntoa(cinarr[i-4].sin_addr),ntohs(cinarr[i-4].sin_port), i, buf); } } } } close(sfd); return 0; }
客户端代码示例
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <netinet/in.h> #define ERR_MSG(msg) do{\ fprintf(stderr, "__%d__:", __LINE__);\ perror(msg);\ }while(0) #define PORT 6666 #define IP "192.168.31.114" //本机IP:ifconfig查看 int main(int argc, const char *argv[]) { //创建流式套接字 int sfd = socket(AF_INET, SOCK_STREAM, 0); if(sfd < 0) { ERR_MSG("socket"); return -1; } //绑定客户端自身的IP地址和端口---->非必须绑定 //填充要连接的服务器的IP和端口 struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(PORT); //服务器绑定的端口 sin.sin_addr.s_addr = inet_addr(IP); //服务器绑定的IP //连接服务器 if(connect(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("connect"); return -1; } printf("connect success\n"); //创建一个读集合 fd_set readfds,tempfds; //清空 FD_ZERO(&readfds); FD_ZERO(&tempfds); //将文件描述符添加进集合 FD_SET(0,&readfds); FD_SET(sfd,&readfds); int maxfd = sfd; int st_res = 0; char buf[128] = ""; ssize_t res = 0; while(1) { tempfds = readfds; st_res = select(maxfd+1,&tempfds,NULL,NULL,NULL); if(st_res < 0) { ERR_MSG("select"); return -1; } else if(0 == st_res) { printf("time out\n"); break; } for(int i=0;i<=maxfd;i++) { if(FD_ISSET(i,&tempfds) == 0) { continue; } //到此说明i在tempfds中 if(0 == i) { bzero(buf, sizeof(buf)); printf("请输入>>>"); fgets(buf, sizeof(buf), stdin); buf[strlen(buf)-1] = 0; //发送 if(send(sfd, buf, sizeof(buf), 0) < 0) { ERR_MSG("send"); return -1; } printf("send success\n"); } //接收 else if(sfd == i) { bzero(buf, sizeof(buf)); res = recv(sfd, buf, sizeof(buf), 0); if(res < 0) { ERR_MSG("recv"); return -1; } else if(0 ==res) { printf("服务器关闭\n"); break; } else { printf("%ld:%s\n",res, buf); } } } } close(sfd); return 0; }
poll的TCP客户端
代码示例
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <poll.h> #define ERR_MSG(msg) do{\ fprintf(stderr, "__%d__:", __LINE__);\ perror(msg);\ }while(0) #define PORT 6666 #define IP "192.168.31.114" //本机IP:ifconfig查看 int main(int argc, const char *argv[]) { //创建流式套接字 int sfd = socket(AF_INET, SOCK_STREAM, 0); if(sfd < 0) { ERR_MSG("socket"); return -1; } //绑定客户端自身的IP地址和端口---->非必须绑定 //填充要连接的服务器的IP和端口 struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(PORT); //服务器绑定的端口 sin.sin_addr.s_addr = inet_addr(IP); //服务器绑定的IP //连接服务器 if(connect(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("connect"); return -1; } printf("connect success\n"); //创建集合 struct pollfd fds[2]; //将文件描述符添加到集合中并监控读事件 fds[0].fd = 0; fds[0].events = POLLIN; fds[1].fd = sfd; fds[1].events = POLLIN; char buf[128] = ""; ssize_t res ; int pl_res =0; while(1) { //判断是否有文件描述符成功触发事件 pl_res = poll(fds,2,-1); if(pl_res < 0) { ERR_MSG("poll"); return -1; } else if(0 == pl_res) { printf("time out\n"); break; } //判断文件描述符对应的revents //fds[0].fd 即0号文件描述符有POLLIN事件发生 if(fds[0].revents & POLLIN) { bzero(buf, sizeof(buf)); printf("请输入>>>"); fgets(buf, sizeof(buf), stdin); buf[strlen(buf)-1] = 0; //发送 if(send(sfd, buf, sizeof(buf), 0) < 0) { ERR_MSG("send"); return -1; } printf("send success\n"); } //sfd文件描述符有POLLIN事件发生 if(fds[1].revents & POLLIN) { //接收 bzero(buf, sizeof(buf)); res = recv(sfd, buf, sizeof(buf), 0); if(res < 0) { ERR_MSG("recv"); return -1; } else if(0 ==res) { printf("服务器关闭\n"); break; } printf(":%s\n", buf); } } close(sfd); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。