- read,write与recv,send
- readline实现
- 用readline实现回射客户、服务器
- getsockname ,getpeername
- gethostname,gethostbyname,gethostbyaddr
- 基于readline的回射客户/服务器
- 服务端
-
1 #include <stdio.h> 2 #include <errno.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <unistd.h> 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <netinet/in.h> 9 #include <arpa/inet.h> 10 11 #define ERR_EXIT(m) 12 do{ 13 perror(m); 14 exit(EXIT_FAILURE); 15 }while(0) 16 17 18 ssize_t readn(int fd, void* buf,size_t count) 19 { 20 size_t nleft = count; 21 ssize_t nread; 22 char *bufp = (char*)buf; 23 24 while(nleft > 0) 25 { 26 if((nread = read(fd,bufp,nleft)) < 0) 27 { 28 if(errno == EINTR) 29 continue; 30 return -1; 31 } 32 else if(nread == 0) 33 { 34 return count-nleft; 35 } 36 37 bufp += nread; 38 nleft -= nread; 39 } 40 return count; 41 } 42 43 ssize_t writen(int fd, void* buf,size_t count) 44 { 45 size_t nleft = count; 46 ssize_t nwrite; 47 char *bufp = (char*)buf; 48 49 while(nleft > 0) 50 { 51 if((nwrite = write(fd,bufp,nleft)) < 0) 52 { 53 if (errno = EINTR) 54 continue; 55 return -1; 56 } 57 else if(nwrite == 0) 58 continue; 59 bufp += nwrite; 60 nleft -= nwrite; 61 } 62 return count; 63 } 64 65 ssize_t recv_peek(int fd, void* buf,size_t count) 66 { 67 while(1) 68 { 69 int ret = recv(fd,buf,count,MSG_PEEK); 70 if(ret == -1 && errno == EINTR) 71 continue; 72 return ret; 73 } 74 } 75 76 ssize_t readline(int sockfd,void *buf,size_t maxline) 77 { 78 int ret; 79 int nread; 80 char *bufp= buf; 81 int nleft =maxline; 82 while(1) 83 { 84 ret = recv_peek(sockfd,bufp,nleft); 85 if(ret < 0) 86 return ret; 87 else if(ret == 0) 88 return ret; 89 nread = ret; 90 int i; 91 for(i = 0; i < nread; i++) 92 { 93 if(bufp[i] == ' ') 94 { 95 ret = readn(sockfd,bufp, i+1); 96 if(ret != i+1) 97 exit(EXIT_FAILURE); 98 return ret; 99 } 100 } 101 if(nread > nleft) 102 exit(EXIT_FAILURE); 103 nleft -= nread; 104 ret = readn(sockfd,bufp,nread); 105 if(ret != nread) 106 exit(EXIT_FAILURE); 107 bufp += nread; 108 } 109 return -1; 110 } 111 112 void do_service(int conn) 113 { 114 char recvbuf[1024]; 115 int n; 116 while(1) 117 { 118 memset(recvbuf,0,sizeof(recvbuf)); 119 int ret = readline(conn,recvbuf,1024); 120 if(ret == -1) 121 ERR_EXIT("read"); 122 if(ret == 0) 123 { 124 printf("clien close"); 125 break; 126 } 127 128 fputs(recvbuf,stdout); 129 writen(conn,recvbuf,strlen(recvbuf)); 130 } 131 } 132 133 int main(void) 134 { 135 int listenfd; 136 if((listenfd = socket(AF_INET,SOCK_STREAM,0)) < 0) 137 ERR_EXIT("socket"); 138 139 struct sockaddr_in servaddr; 140 memset(&servaddr, 0, sizeof(servaddr)); 141 servaddr.sin_family = AF_INET; 142 servaddr.sin_port = htons(5188); 143 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 144 145 int on; 146 if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 147 ERR_EXIT("setsockopt"); 148 if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0) 149 ERR_EXIT("bind"); 150 if(listen(listenfd,SOMAXCONN) < 0) 151 ERR_EXIT("listen"); 152 struct sockaddr_in peeraddr; 153 socklen_t peerlen = sizeof(peeraddr); 154 int conn; 155 156 pid_t pid; 157 while(1) 158 { 159 if((conn = accept(listenfd,(struct sockaddr*)&peeraddr,&peerlen)) < 0) 160 ERR_EXIT("accept"); 161 printf("ip=%s,port=%d ",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port)); 162 163 pid = fork(); 164 if(pid == -1) 165 ERR_EXIT("fork"); 166 if(pid == 0) 167 { 168 close(listenfd); 169 do_service(conn); 170 exit(EXIT_SUCCESS); 171 } 172 else 173 close(conn); 174 } 175 return 0; 176 }
-
- 客户端
-
1 #include <stdio.h> 2 #include <errno.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <unistd.h> 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <netinet/in.h> 9 #include <arpa/inet.h> 10 11 #define ERR_EXIT(m) 12 do{ 13 perror(m); 14 exit(EXIT_FAILURE); 15 }while(0) 16 17 ssize_t readn(int fd, void* buf,size_t count) 18 { 19 size_t nleft = count; 20 ssize_t nread; 21 char *bufp = (char*)buf; 22 23 while(nleft > 0) 24 { 25 if((nread = read(fd,bufp,nleft)) < 0) 26 { 27 if(errno == EINTR) 28 continue; 29 return -1; 30 } 31 else if(nread == 0) 32 { 33 return count-nleft; 34 } 35 36 bufp += nread; 37 nleft -= nread; 38 } 39 return count; 40 } 41 42 ssize_t writen(int fd, void* buf,size_t count) 43 { 44 size_t nleft = count; 45 ssize_t nwrite; 46 char *bufp = (char*)buf; 47 48 while(nleft > 0) 49 { 50 if((nwrite = write(fd,bufp,nleft)) < 0) 51 { 52 if (errno = EINTR) 53 continue; 54 return -1; 55 } 56 else if(nwrite == 0) 57 continue; 58 bufp += nwrite; 59 nleft -= nwrite; 60 } 61 return count; 62 } 63 64 size_t recv_peek(int fd, void* buf,size_t count) 65 { 66 while(1) 67 { 68 int ret = recv(fd,buf,count,MSG_PEEK); 69 if(ret == -1 && errno == EINTR) 70 continue; 71 return ret; 72 } 73 } 74 75 ssize_t readline(int sockfd,void *buf,size_t maxline) 76 { 77 int ret; 78 int nread; 79 char *bufp= buf; 80 int nleft =maxline; 81 while(1) 82 { 83 ret = recv_peek(sockfd,bufp,nleft); 84 if(ret < 0) 85 return ret; 86 else if(ret == 0) 87 return ret; 88 nread = ret; 89 int i; 90 for(i = 0; i < nread; i++) 91 { 92 if(bufp[i] == ' ') 93 { 94 ret = readn(sockfd,bufp, i+1); 95 if(ret != i+1) 96 exit(EXIT_FAILURE); 97 return ret; 98 } 99 } 100 if(nread > nleft) 101 exit(EXIT_FAILURE); 102 nleft -= nread; 103 ret = readn(sockfd,bufp,nread); 104 if(ret != nread) 105 exit(EXIT_FAILURE); 106 bufp += nread; 107 } 108 return -1; 109 } 110 111 int main(void) 112 { 113 int sock; 114 if((sock= socket(AF_INET,SOCK_STREAM,0)) < 0) 115 ERR_EXIT("socket"); 116 117 struct sockaddr_in servaddr; 118 memset(&servaddr, 0, sizeof(servaddr)); 119 servaddr.sin_family = AF_INET; 120 servaddr.sin_port = htons(5188); 121 servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 122 123 if(connect(sock,(struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) 124 ERR_EXIT("connect"); 125 126 struct sockaddr_in localaddr; 127 socklen_t addrlen = sizeof(localaddr); 128 if(getsockname(sock,(struct sockaddr*)&localaddr,&addrlen) < 0) 129 ERR_EXIT("getsockname"); 130 printf("ip=%s,port=%d ",inet_ntoa(localaddr.sin_addr),ntohs(localaddr.sin_port)); 131 char sendbuf[1024] = { 0 }; 132 char recvbuf[1024] = { 0 }; 133 int n; 134 while(fgets(sendbuf,sizeof(sendbuf),stdin) != NULL) 135 { 136 writen(sock,sendbuf,strlen(sendbuf)); 137 int ret = readline(sock,recvbuf,sizeof(sendbuf)); 138 if(ret == -1) 139 ERR_EXIT("readn"); 140 else if(ret == 0) 141 { 142 printf("client close"); 143 break; 144 } 145 146 fputs(recvbuf,stdout); 147 // fputs(recvbuf,stdout); 148 149 memset(sendbuf,0, sizeof(sendbuf)); 150 memset(recvbuf,0, sizeof(recvbuf)); 151 } 152 close(sock); 153 return 0; 154 }
-
- 服务端
- gethostname
1 #include <stdio.h> 2 #include <errno.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <unistd.h> 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <netinet/in.h> 9 #include <arpa/inet.h> 10 #include <netdb.h> 11 12 #define ERR_EXIT(m) 13 do{ 14 perror(m); 15 exit(EXIT_FAILURE); 16 }while(0) 17 18 int getlocalip(char *ip) 19 { 20 char host[100] = { 0 }; 21 if(gethostname(host,sizeof(host)) < 0) 22 return -1; 23 24 struct hostent *hp; 25 if((hp = gethostbyname(host)) == NULL) 26 return -1; 27 28 strcpy(ip,inet_ntoa(*(struct in_addr*)hp->h_addr_list[0])); 29 return 0; 30 } 31 32 int main() 33 { 34 char host[100] = { 0 }; 35 if(gethostname(host,sizeof(host)) < 0) 36 ERR_EXIT("gethostname"); 37 38 struct hostent *hp; 39 if((hp = gethostbyname(host)) == NULL) 40 ERR_EXIT("gethostbyname"); 41 42 int i = 0; 43 while(hp->h_addr_list[i] != NULL) 44 { 45 printf("%s ",inet_ntoa(*(struct in_addr*)hp->h_addr_list[i])); 46 i++; 47 } 48 char ip[16] = { 0 }; 49 getlocalip(ip); 50 printf("localip=%s ",ip); 51 return 0; 52 }