标签:
sug.c
1 /* 2 * 单词自动补全功能 3 * File: search.c 4 * Author: baijianmin 5 */ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <errno.h> 11 #include <stdarg.h> 12 #include <time.h> 13 14 #include <sys/socket.h> 15 #include <netinet/in.h> 16 #include <arpa/inet.h> 17 18 #define MAX_CHILD 26 19 #define LISTEN_PORT 8080 20 #define LOG_DEBUG_PATH "./logs/debug.log" 21 #define LOG_ERROR_PATH "./logs/error.log" 22 #define DATA_PATH "one.txt" 23 24 /** 25 * define log level 26 */ 27 enum log_level { 28 DEBUG = 0, 29 ERROR = 1 30 }; 31 32 #define error(...) 33 logger(ERROR, __LINE__, __VA_ARGS__) 34 35 #define debug(...) 36 logger(DEBUG, __LINE__, __VA_ARGS__) 37 38 #define assert(expr, rc) 39 if(!(expr)){ 40 error(#expr"is null or 0"); 41 return rc; 42 } 43 44 /** 45 * trie node 46 */ 47 typedef struct node_s { 48 int count; 49 struct node_s *child[MAX_CHILD]; 50 char words[20]; 51 } node_t; 52 53 /** 54 * global var 55 */ 56 node_t *global_root; 57 58 59 /** 60 * get now timestr 61 */ 62 static void get_time(char *time_str, size_t len) { 63 time_t tt; 64 struct tm local_time; 65 time(&tt); 66 localtime_r(&tt, &local_time); 67 strftime(time_str, len, "%m-%d %H:%M:%S", &local_time); 68 } 69 70 /** 71 * log 72 */ 73 static void logger(int flag, int line, const char *fmt, ...) { 74 FILE *fp = NULL; 75 char time_str[20 + 1]; 76 va_list args; 77 get_time(time_str, sizeof(time_str)); 78 79 switch (flag) { 80 case DEBUG: 81 fp = fopen(LOG_DEBUG_PATH, "a"); 82 if (!fp) { 83 return; 84 } 85 fprintf(fp, "%s DEBUG (%d:%d) ", time_str, getpid(), line); 86 break; 87 case ERROR: 88 fp = fopen(LOG_ERROR_PATH, "a"); 89 if (!fp) { 90 return; 91 } 92 fprintf(fp, "%s ERROR (%d:%d) ", time_str, getpid(), line); 93 break; 94 default: 95 return; 96 } 97 98 va_start(args, fmt); 99 vfprintf(fp, fmt, args); 100 va_end(args); 101 fprintf(fp, "\n"); 102 103 fclose(fp); 104 return; 105 } 106 107 /** 108 * listen fro connections on a specified port 109 */ 110 int startup() { 111 int sockfd = -1; 112 struct sockaddr_in addr; 113 memset(&addr, 0, sizeof (addr)); 114 sockfd = socket(AF_INET, SOCK_STREAM, 0); 115 if (sockfd < 0) { 116 error("socket fail: %s", strerror(errno)); 117 return -1; 118 } 119 addr.sin_family = AF_INET; 120 addr.sin_port = htons(LISTEN_PORT); 121 addr.sin_addr.s_addr = htonl(INADDR_ANY); 122 if (bind(sockfd, (struct sockaddr *) &addr, sizeof (addr))) { 123 error("bind fail: %s", strerror(errno)); 124 return -1; 125 } 126 if (listen(sockfd, 5)) { 127 error("listen fail: %s", strerror(errno)); 128 return -1; 129 } 130 return sockfd; 131 } 132 133 /** 134 * create node 135 */ 136 node_t *createNode() { 137 node_t *node = (node_t *) calloc(1, sizeof (node_t)); 138 if (node == NULL) { 139 error("createNode fail: %s", strerror(errno)); 140 } 141 } 142 143 /** 144 * insert words 145 */ 146 int insert(node_t *root, char *words) { 147 if (!root || words[0] == ‘\0‘) { 148 error("insert fail, root or words is null"); 149 return -1; 150 } 151 node_t *node = root; 152 node_t *tmp; 153 char *s = words; 154 while (*s != ‘\0‘) { 155 if (node->child[*s - ‘a‘] == NULL) { 156 tmp = createNode(); 157 if (tmp == NULL) { 158 goto err; 159 } 160 node->child[*s - ‘a‘] = tmp; 161 } 162 node = node->child[*s - ‘a‘]; 163 s++; 164 } 165 node->count++; 166 memcpy(node->words, words, strlen(words)); 167 return 0; 168 err: 169 return -1; 170 } 171 172 void search_child(node_t *node, int client_sock) { 173 if (!node) { 174 error("search_child fail, node is null"); 175 return; 176 } 177 int i; 178 if (node->count) { 179 send(client_sock, node->words, strlen(node->words), 0); 180 send(client_sock, "|", 1, 0); 181 } 182 for (i = 0; i < MAX_CHILD; i++) { 183 if (node->child[i]) { 184 search_child(node->child[i], client_sock); 185 } 186 } 187 } 188 189 /** 190 * search 191 */ 192 int search(node_t *root, char *words, int client_sockfd) { 193 //--------------------------------fixme------------------------------------- 194 char *ps = words; 195 while (*ps != ‘\0‘) { 196 if (*ps < ‘a‘ || *ps > ‘z‘) { 197 *ps = ‘\0‘; 198 break; 199 } 200 ps++; 201 } 202 //-------------------------------------------------------------------------- 203 if (!root || words[0] == ‘\0‘) { 204 error("search fail, root or words is null"); 205 return -1; 206 } 207 debug("request query: %s", words); 208 char *s = words; 209 node_t *node = root; 210 while (*s != ‘\0‘) { 211 if (node->child[*s - ‘a‘] == NULL) { 212 break; 213 } 214 node = node->child[*s - ‘a‘]; 215 s++; 216 } 217 if (*s == ‘\0‘) { 218 #if 0 219 if (node->count == 0) { 220 printf("没有搜索到这个字符串,但是它是某个字符串的前缀\n"); 221 } else { 222 printf("搜索到此字符串,出现次数为:%d\n", node->count); 223 } 224 #endif 225 search_child(node, client_sockfd); 226 227 } else { 228 #if 0 229 printf("没有搜索到这个字符串:%s, %d\n", words, strlen(words)); 230 #endif 231 } 232 close(client_sockfd); 233 } 234 235 /** 236 * free mem 237 */ 238 void del(node_t *root) { 239 if (!root) { 240 error("del fail, root is null"); 241 return; 242 } 243 244 int i; 245 for (i = 0; i < MAX_CHILD; i++) { 246 if (root->child[i]) { 247 del(root->child[i]); 248 } 249 } 250 free(root); 251 252 } 253 254 /** 255 * load data from file 256 */ 257 int load_data() { 258 global_root = createNode(); 259 if(!global_root){ 260 return -1; 261 } 262 FILE *fp = fopen(DATA_PATH, "r"); 263 if (!fp) { 264 error("open fail fail: %S", strerror(errno)); 265 return -1; 266 } 267 char words[20]; 268 while (!feof(fp) && fgets(words, sizeof (words), fp)) { 269 words[strlen(words) - 1] = ‘\0‘; 270 insert(global_root, words); 271 memset(words, 0, sizeof (words)); 272 } 273 debug("load_data success"); 274 return 0; 275 } 276 277 /** 278 * response the request 279 */ 280 void accept_request(int client_sockfd){ 281 char buf[20]; 282 memset(buf, 0, sizeof(buf)); 283 recv(client_sockfd, buf, sizeof(buf), 0); 284 search(global_root, buf, client_sockfd); 285 //close client connection 286 close(client_sockfd); 287 } 288 289 int main(void) { 290 int server_sockfd = -1, client_sockfd = -1; 291 struct sockaddr_in client_addr; 292 memset(&client_addr, 0, sizeof (client_sockfd)); 293 int addr_len = sizeof (client_sockfd); 294 295 server_sockfd = startup(); 296 if (server_sockfd < 0) { 297 return -1; 298 } 299 300 //load data from file 301 load_data(); 302 303 //waitting for client 304 while (1) { 305 client_sockfd = accept(server_sockfd, 306 (struct sockaddr *) &client_addr, &addr_len); 307 if(client_sockfd < 0){ 308 error("accept fail, %s", strerror(errno)); 309 return -1; 310 } 311 accept_request(client_sockfd); 312 } 313 314 close(server_sockfd); 315 return 0; 316 }
sug.php
<?php if($_GET[‘query‘]){ $query = $_GET[‘query‘]; }else{ exit(json_encode(array())); } $host = "127.0.0.1"; $port = "8080"; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Unable to create socket\n"); @socket_connect($socket, $host, $port) or die("Connect error.\n"); if ($err = socket_last_error($socket)){ socket_close($socket); die(socket_strerror($err) . "\n"); } $len = socket_write ($socket , $query, strlen($query)); $querys = ""; $ret = socket_read($socket, 100); while($ret){ $querys.=$ret; $ret = socket_read($socket, 100); } socket_close($socket); $querysArr = explode("|", $querys); array_pop($querysArr); echo json_encode($querysArr);
效果:
http://www.idoushuo.com/sug.php?query=a
标签:
原文地址:http://www.cnblogs.com/bai-jimmy/p/5428186.html