UNP——TCP回射服务器
2020-07-01 17:57
106 查看
非阻塞connect
server
#include <stdio.h> #include <stdlib.h> #include "tcpser.h" #include <arpa/inet.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <sys/select.h> #include <errno.h> #define LISTSIZE 50 //#define MAX(a,b)((a)>(b)? (a):(b)) #define ADDRBUFFER 50 #define RECV_BUFSIZE 1024 int main() { fd_set* r_set,w_set,e_set; int sd,wd; int nsd; ssize_t num; int flag; char recv_buffer[RECV_BUFSIZE]; char addr_buffer[ADDRBUFFER]; struct sockaddr_in laddr, raddr; struct timeval timel; timel.tv_sec = 60; int raddr_size = sizeof(raddr); // fp = fopen(); // int fd = fileno(fp); sd = socket(AF_INET,SOCK_STREAM,0); if(sd<0) { perror("socket"); exit(1); } if(setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag))<0) { perror("setsockopt"); exit(1); } laddr.sin_family = AF_INET; laddr.sin_port = htons(PORT); inet_pton(AF_INET,"0.0.0.0",(void*)&laddr.sin_addr); if(bind(sd,(void*)&laddr,sizeof(laddr))<0) { perror("bind"); exit(1); } if(listen(sd,LISTSIZE)<0) { perror("listen"); exit(1); } while(1) { FD_ZERO(r_set); //FD_ZERO(w_set); FD_SET(sd,r_set); //FD_SET(fd,w_set); switch(select(sd+1,r_set,NULL,NULL,&timel)) { case 0: { fprintf(stdout,"timeout\n"); break; } case -1: { if(errno == EINTR) continue; else { perror("select"); break; } } default: { if(FD_ISSET(sd,r_set)) { nsd = accept(sd,(void*)&raddr,(void*)&raddr_size); if( nsd < 0) { perror("accept"); exit(1); } inet_ntop(AF_INET,(void*)&raddr.sin_addr,addr_buffer,ADDRBUFFER); printf("the client ip is %s, port is %d\n",addr_buffer,ntohs(raddr.sin_port)); while(1) { num = recv(nsd,recv_buffer,RECV_BUFSIZE,0); if(num == 0) { printf("end \n"); break; } else if(num<0) { perror("recv"); exit(1); } if(write(nsd,recv_buffer,num)<0) { perror("write"); exit(1); } } close(nsd); } } } } close(sd); exit(0); }
client,connect非阻塞版本
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/select.h> #include <string.h> #include <strings.h> #include "tcpser.h" #include <fcntl.h> #include <errno.h> #define MAXLINE 1024 int main(int argc, char* argv[]) { int sockfd; int n; struct sockaddr_in servaddr; char buf[MAXLINE]; fd_set rset, wcoset; int maxfd; int stdineof; if(argc != 2){ printf("invalid usage!\n"); exit(1); } if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ perror("socket"); exit(1); } servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); inet_pton(AF_INET, argv[1], &servaddr.sin_addr); int fcmd = fcntl(sockfd,F_GETFL,0); //返回原来的文件标志 fcntl(sockfd,F_SETFL,O_NONBLOCK|fcmd); //在原来的文件标志的基础上增加非阻塞标志 if(connect(sockfd, (void*)&servaddr, sizeof(servaddr)) < 0){ //perror("socket"); if(errno == EINPROGRESS) { FD_SET(0, &wcoset); FD_SET(sockfd, &wcoset); if(select(sockfd+1,NULL,&wcoset,NULL,NULL)<0) { perror("select"); exit(1); } if(FD_ISSET(sockfd, &wcoset)) { int flag; socklen_t sflag = sizeof(flag); if(getsockopt(sockfd,SOL_SOCKET,SO_ERROR,(void*)&flag,&sflag)<0) { printf("the error is : %s\n",strerror(flag)); exit(1); } printf("conncet 2 successifully\n"); } } } else { printf("conncet 1 successifully\n"); } maxfd = sockfd; FD_ZERO(&rset); stdineof = 0; while(1){ if(stdineof == 0) FD_ZERO(&rset); FD_SET(sockfd, &rset); if((n = select(maxfd+1, &rset, NULL, NULL, NULL)) < 0){ printf("select error\n"); exit(1); } if(FD_ISSET(0, &rset)){ if((n = read(0, buf, MAXLINE)) == 1){ printf("shutdown ready\n"); stdineof = 1; if(shutdown(sockfd, SHUT_RD) < 0){ perror("shutdown"); exit(1); } FD_CLR(0, &rset); continue; } else if(n < 0){ perror("read"); exit(1); } if((n = write(sockfd, buf, n)) < 0){ perror("write"); exit(1); } } if(FD_ISSET(sockfd, &rset)){ if((n = read(sockfd, buf, MAXLINE)) == 0){ if(stdineof == 1) break; else{ printf("server terminated\n"); exit(1); } } else if(n < 0){ perror("read"); exit(1); } if((n = write(1, buf, n)) < 0){ perror("write"); exit(1); } } } return 0; }
h文件
#ifndef TCPSER_H_ #define TCPSER_H_ #define PORT 2010 #endif
相关文章推荐
- TCP并发服务器(七)——可动态增减的线程池,主线程accept——基于UNP代码修改
- TCP并发服务器(六)——创建线程池,每个线程accept,accept使用互斥锁保护——基于UNP代码
- (UNP点滴记录) TCP端口号与并发服务器,缓冲区大小限制,TCP/UDP输出机制
- 在向服务器发送请求时发生传输级错误。 (provider: TCP 提供程序, error: 0 - 远程主机强迫关闭了一个现有的连接。) ---> System.Data.SqlClient.Sql
- Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)(解决不可连的问题,解决方案在最后面)
- linux网络编程——TCP文件服务器
- python实现可将字符转换成大写的tcp服务器实例
- 【Java TCP/IP Socket】基于线程池的TCP服务器(含代码)
- 使用netty4.x 编写TCP服务器关于握手问题
- TCP服务器“拒绝服务攻击” 解决方案
- 用Python实现一个简单的多线程TCP服务器的教程
- socket之TCP多线程客户服务器编程
- Pythoh网络编程3:创建TCP服务器和客户端
- MFC TCP服务器
- UNP-UNIX网络编程 第五章:TCP客户/服务器程序示例
- python 创建TCP服务器、客户端程序
- 单片机之UIP--TCP作为服务器,主动发送数据 ACK
- UNIX TCP回射服务器/客户端(4):使用epoll模型的服务器
- C++ Qt多线程 TcpSocket服务器实例
- 基于TCP的服务器与客户端的简单交互2