解决用户在搜索引擎乱输入,无空格或间接输入,进行分割

现在经常会有一个用户在搜索引擎中输入不加空格或者分割符的,近来写了一个小小的代码,用一个词库,来匹配用户输入的单词或者是其他的东西,最后以空格分割输出。以下是一个简单的ruby程序。利用hash进行索引,查询速更快。  

 1 $stack = []
 2 $scan_str  = File.read("#{File.dirname(__FILE__)}/word.txt").scan(/(.*)[/) 
 3 $a = ""   #用来装不能分割单词的情况
 4 def get_word
 5   puts "请输入需要搜索的内容"
 6   sum = 0 
 7   #for i in 0..100
 8      str = gets.chomp()
 9     #str = "ukcfefweiufweifhf"
10     t1 = Time.new
11     h = Hash.new()
12     for i in 0..$scan_str.length-1
13       h["#{$scan_str[i][0]}"]=1  
14     end
15     if h.key?str
16        puts "你搜索的结果为:#{str}"
17        return   
18     else
19        i = 0  #递归开始的位置
20        j = 0  #数组下标
21        k = 1  #每次开始的位置
22        fun(str,i,j,k)
23        if $a.length>0&&$stack.length==0    
24           puts "输入的单词可能错误哦 可能的搜索为结果:#{$a}"
25        end
26        if $a.length==0
27           puts "没有符合的"
28        end
29        $stack = []
30        $a = ""
31        t2 = Time.new
32        c = t2-t1
33        puts "执行代码的时间为:#{t2-t1}"
34        #sum = sum + c
35     end
36   #end 
37   #puts "总时间为:#{sum}"
38   #puts "平均时间为:#{sum/100}" 
39 end
40   
41 def fun(str,i,j,k)
42   h = Hash.new()
43   for z in 0..$scan_str.length-1
44     h["#{$scan_str[z][0]}"]=1
45   end 
46   if str.length.eql?$stack.join("").length  #数组转string join("")
47     puts "搜索的结果为:
 #{$stack.join(" ")}"   #以空格分开 输出
48     return 
49   end
50   q = []
51   while !str.length.eql?$stack.join("").length
52      q[j]=str[i,k]
53      #puts "j = #{j}, k = #{k}"
54      #puts "fun的str:#{str}"
55      #puts "fun的q:#{q}"
56      #puts "第#{j}个单词:#{q[j]}"
57      if h.key?q[j]
58        #puts "找到单词:#{q[j]},找到啦  找到啦"   
59        $stack.push(q[j])
60        $stack.push("")
61        #puts "匹配入栈的值:#{$stack}"
62        $a = q[j]
63        fun(str,$stack.join("").length,j+1,1)
64        #puts "栈的值:#{$stack}"
65      end 
66      #puts "q[str.length-1]:#{q[str.length-1]}"
67      j = j+1
68      k = k+1
69      if q[str.length-1]!=nil  #如果后面的单词不匹配
70        if !h.key?q[str.length-1]
71         $stack.pop
72         $stack.pop 
73         return 
74        end 
75      end
76   end  
77 end
ruby代码

但是考虑到用ruby的话,运行时间上来看还是没有用c写的快,于是用了linux-c socket编程写了两个程序--客户端+服务器(客户端负责输入,服务器负责查询最后将结果传回客户端先采用udp,可以多个客户端调用,因为udp是无序的)(更推荐)

#include <netinet/in.h>    // for sockaddr_in
#include <sys/types.h>    // for socket
#include <sys/socket.h>    // for socket
#include <stdio.h>        
#include <stdlib.h>        // for exit  
#include <string.h>        // for bzero
#include <time.h>
#define PORT    6996
#define BUFFER_SIZE 1024
#define N 1024
 
char *words[20000];
 
int main(int argc, char **argv)
{
    clock_t start, end;
    char str[N];
    int n=0;
    
    FILE *fp;
    if( (fp=fopen("key_string.txt","r")) == NULL ){
        printf("Cannot open file, press enter to exit!
");
       return ;
    }
    while(fgets(str, N, fp) != NULL){
        if(strlen(str)==N)
            continue;
        words[n] = (char*)malloc(1024*sizeof(char));   //每次动态开一个
        sscanf(str,"%[^
]",words[n]);    //匹配            
        n++;
    }
    n--;
    
    printf("key_string.txt的词数有:%d
",n);
    if (argc != 2)
    {
        printf("Please Input Server IP Address
");
        exit(1);
    }

    int client_socket = socket(AF_INET,SOCK_DGRAM,0);
    if( client_socket < 0)
    {
        printf("Create Socket Failed!
");
        exit(1);
    }

        //设置一个socket地址结构server_addr,代表服务器的internet地址, 端口
    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr=inet_addr(argv[1]);

    while(n!=-1){
        char send_buffer[BUFFER_SIZE];
        bzero(send_buffer,BUFFER_SIZE);
        strcpy(send_buffer,words[n]);
        printf("-----------------------------------------------------------------
");
        printf("第%d的是:%s
",n,words[n]);
       
        //向服务器发送buffer中的数据
         if(sendto(client_socket,send_buffer,BUFFER_SIZE,0,(struct sockaddr *)&server_addr,sizeof(server_addr))<0){
                    printf("Server Send Failed
");
                    break;
         }
        //从服务器接收数据到buffer中
        char recv_buffer[BUFFER_SIZE];
        bzero(recv_buffer,BUFFER_SIZE);
        int length = 0;
        length = recvfrom(client_socket,recv_buffer,BUFFER_SIZE,0,NULL,NULL);
        if(length < 0)
        {
            printf("Recieve Data From Server  Failed!
" );
            break;
        }
        printf("Search Result -- %s 
",recv_buffer);
        bzero(recv_buffer,BUFFER_SIZE); 
        printf("此时n的值为:%d
",n);
        n--;
        //关闭socket

    }
    fclose(fp);
    close(client_socket);
    return 0;
}
client_udp
#include <netinet/in.h>    // for sockaddr_in
#include <sys/types.h>    // for socket
#include <sys/socket.h>    // for socket
#include <stdio.h>       
#include <stdlib.h>        // for exit  
#include <string.h>        // for bzero

#define PORT    6996
#define LISTEN_COUNT 20
#define BUFFER_SIZE 1024

#define N 60
#define HASHSIZE 2000000   //开辟一个数组
char* words[1600000];
char* search[BUFFER_SIZE];
int k = 0,size=0;//size用来判断当前移动单词的位置
 
 typedef struct _node{
    char * word;
    struct _node *next;
}node;

static node* hashtab[HASHSIZE];
//初始化 
void inithashtab(){
    int i;
    for(i=0;i<HASHSIZE;i++)
        hashtab[i]=NULL;
}
//计算hash
unsigned int hash(char *s){    
    unsigned int h=0;
    for(;*s;s++){
        h=*s+h*N;
    }
    return h%HASHSIZE;
}
//找单词
node* lookup(char *n){
    unsigned int hi=hash(n);
    node* np=hashtab[hi];
    for( ;np!=NULL;np=np->next){
        if(!strcmp(np->word,n)&&np->word!=NULL&&n!=NULL){     //是否等
            return np;
        }
    }
    return NULL;
}
//存单词
char* save(char *o){  
    int l=strlen(o)+1;
    char *ns=(char*)malloc(l*sizeof(char));
    strcpy(ns,o);
    if(ns==NULL)
        return NULL;
    else
        return ns;
}
//获取 根据单词
char* get(char* word){
    node* n=lookup(word);
    if(n==NULL)
        return NULL;
    else
        return n->word;
}
//插入
int insert(char* word){  
    unsigned int hi;
    node* np;
    if((np=lookup(word))==NULL){       //先找
        hi=hash(word);                          //找不到 再分配
        np=(node*)malloc(sizeof(node));
        if(np==NULL)
            return 0;
        np->word=save(word);     //保存
        if(np->word==NULL) 
            return 0;
        np->next=hashtab[hi];  //插入的时候 如果发现冲突 就往链表里扔
        hashtab[hi]=np;
    }
    return 1;
}
//分割单词 找单词
int devide(char* word,int start){
    char *q;
    char a[BUFFER_SIZE]={},instead;
    size = strlen(word);
    while(*word&&size>0){
        instead = *word;
        a[start] = instead;
        //printf("a的值:%s
",a);
        q = a;
        if(get(a)){
            printf("找到啦~这个单词是:%s
",a);
            search[k++] = q;
            search[k++] = " ";
            word++;
            devide(word,0);          
            word--;
        }
        start++;
        word++;    
        if(strlen(word)==0){
            if(!get(q)){
                 search[--k]="";
                 search[--k]="";
            }
        }
    }
    if(k<=0){     //里面一个都没有
        return 0;
    }
    return 1;
}
 
int main(int argc, char **argv)
{
    FILE *fp;
    char str[N+1];
    int i = 0,n=0,s,count=0,flag=0,out_length;
    int c=0;
    if( (fp=fopen("yes.txt","r")) == NULL ){
        printf("Cannot open file, press enter to exit!
");
       return ;
    }
    while(fgets(str, N, fp) != NULL){
        words[n] = (char*)malloc(50*sizeof(char));   //每次动态开一个
        sscanf(str,"%[^:]",words[n]);    //匹配            
        //printf("第%d个单词是:%s
",n,words[n]);
        n++;
    }
    
    printf("统计单词数:%d
",n);
    printf("-----------------------------------------------------------------
");

    s = sizeof(words) / sizeof(words[0]);
    inithashtab();
    for(i=0;i<s;i++){   
        if(words[i]==NULL)
            break;
        insert(words[i]);
    }     
 
    //server_socket代表服务器socket
    int server_socket = socket(AF_INET,SOCK_DGRAM,0);
    if( server_socket < 0)
    {
        printf("Create Socket Failed!");
        exit(1);
    }

    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(server_addr)); //把一段内存区的内容清零
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY表示自动获取本机地址
    server_addr.sin_port = htons(PORT); 
   
    if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)) <0)
    {
        printf("Server Bind Port : %d Failed!", PORT); 
        exit(1);   
    }
    struct sockaddr_in cli_addr;
    int cli_size = sizeof(cli_addr);
    char send_buffer[BUFFER_SIZE];
    char recv_buffer[BUFFER_SIZE];
    while (1) //服务器端要一直运行
    {    
        bzero(recv_buffer,BUFFER_SIZE);
        bzero(send_buffer,BUFFER_SIZE);    
        k = 0,size=0;
        int length = recvfrom(server_socket,recv_buffer,sizeof(recv_buffer),0,(struct sockaddr *)&cli_addr,&cli_size);        
        if(length < 0 ){
            printf("Server Recv Failed
");
            break;
        }    
        printf("收到:%s
",recv_buffer);
        if(get(recv_buffer)){    //索引判断是否存在
            printf("Result -- %s !
",get(recv_buffer));                    
            if(sendto(server_socket,recv_buffer,sizeof(recv_buffer),0,(struct sockaddr *)&cli_addr,cli_size)<0){
                    printf("Server Send Failed
");
                    break;
            }
            continue;    
        }
        else
            flag = devide(recv_buffer,0);
        if(flag){
            printf("Result -- ");
            for(i=0;i<k-1;i++){
                printf("%s",search[i]);
                strcat(send_buffer,search[i]);   //拼接 指针数组送不过去
            }
            printf("
");
            if(sendto(server_socket,send_buffer,sizeof(send_buffer),0,(struct sockaddr *)&cli_addr,cli_size)<0){
                    printf("Server Send Failed
");
                    break;
            }
        }
        else{        
            printf("No Search ! 
");
            bzero(send_buffer,BUFFER_SIZE);
            strcat(send_buffer,"No Find ! ");
            if(sendto(server_socket,send_buffer,sizeof(send_buffer),0,(struct sockaddr *)&cli_addr,cli_size)<0)
                {
                    printf("Server Send Failed
");
                    break;
                }
        }
        printf("-----------------------------------------------------------------
");
    }
    for(i=0;i<n;i++){
        free(words[i]);    //释放空间
    }
    fclose(fp);
    //关闭监听用的socket
    close(server_socket);
    return 0;
}
server_udp

tcp的服务器和客户端,服务器可以采用fork编程,通过父子进程实现多个客户端的调用

  1 #include <netinet/in.h>    // for sockaddr_in
  2 #include <sys/types.h>    // for socket
  3 #include <sys/socket.h>    // for socket
  4 #include <stdio.h>        
  5 #include <stdlib.h>        // for exit  
  6 #include <string.h>        // for bzero
  7 #include <time.h>
  8 #define PORT    8558
  9 #define BUFFER_SIZE 1024
 10 #define N 1024
 11  
 12 char *words[20000];
 13  
 14 int main(int argc, char **argv)
 15 {
 16     clock_t start, end;
 17     char str[N];
 18     int n=0;
 19     
 20     FILE *fp;
 21     if( (fp=fopen("key_string.txt","r")) == NULL ){
 22         printf("Cannot open file, press enter to exit!
");
 23        return ;
 24     }
 25     while(fgets(str, N, fp) != NULL){
 26         if(strlen(str)==N)
 27             continue;
 28         words[n] = (char*)malloc(1024*sizeof(char));   //每次动态开一个
 29         sscanf(str,"%[^
]",words[n]);    //匹配            
 30         n++;
 31     }
 32     n--;
 33     
 34     printf("key_string.txt的词数有:%d
",n);
 35     if (argc != 2)
 36     {
 37         printf("Please Input Server IP Address
");
 38         exit(1);
 39     } 
 40     
 41     //设置一个socket地址结构client_addr  
 42     struct sockaddr_in client_addr;
 43     bzero(&client_addr,sizeof(client_addr)); 
 44     client_addr.sin_family = AF_INET;    //internet协议族  PF_INET 也可以
 45     client_addr.sin_addr.s_addr = inet_addr(argv[1]);
 46     client_addr.sin_port = htons(0);    //0表示让系统自动分配一个空闲端口
 47 
 48     int client_socket = socket(AF_INET,SOCK_STREAM,0);
 49     if( client_socket < 0)
 50     {
 51         printf("Create Socket Failed!
");
 52         exit(1);
 53     }
 54 
 55         //设置一个socket地址结构server_addr,代表服务器的internet地址, 端口
 56     struct sockaddr_in server_addr;
 57     bzero(&server_addr,sizeof(server_addr));
 58     server_addr.sin_family = AF_INET;
 59     server_addr.sin_port = htons(PORT);
 60     int server_addr_length = sizeof(server_addr);
 61      //向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接 
 62     //三次握手
 63      if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0)
 64     {
 65         printf("Can Not Connect To %s!
",argv[1]);
 66         exit(1);
 67     }
 68 
 69     while(n!=-1){
 70         char input[BUFFER_SIZE]={};
 71         strcpy(input,words[n]);
 72         printf("-----------------------------------------------------------------
");
 73         printf("第%d的是:%s
",n,words[n]);
 74         char buffer[BUFFER_SIZE];
 75         bzero(buffer,BUFFER_SIZE);
 76        
 77         //向服务器发送buffer中的数据
 78          if(send(client_socket,input,BUFFER_SIZE,0)<0){
 79                     printf("Server Send Failed
");
 80                     break;
 81          }
 82         //从服务器接收数据到buffer中
 83         bzero(buffer,BUFFER_SIZE);
 84         int length = 0;
 85         length = recv(client_socket,buffer,BUFFER_SIZE,0);
 86         if(length < 0)
 87         {
 88             printf("Recieve Data From Server  Failed!
" );
 89             break;
 90         }
 91         printf("Search Result -- %s 
",buffer);
 92         bzero(buffer,BUFFER_SIZE); 
 93         printf("此时n的值为:%d
",n);
 94         n--;
 95         //关闭socket
 96 
 97     }
 98     fclose(fp);
 99     close(client_socket);
100     return 0;
101 }
client_tcp_fork
#include <netinet/in.h>    // for sockaddr_in
#include <sys/types.h>    // for socket
#include <sys/socket.h>    // for socket
#include <stdio.h>       
#include <stdlib.h>        // for exit  
#include <string.h>        // for bzero

#define PORT    8558
#define LISTEN_COUNT 20
#define BUFFER_SIZE 1024

#define N 60
#define HASHSIZE 2000000   //开辟一个数组
char* words[1600000];
char* search[BUFFER_SIZE];
int k = 0,size=0;//size用来判断当前移动单词的位置
 
 typedef struct _node{
    char * word;
    struct _node *next;
}node;

static node* hashtab[HASHSIZE];
//初始化 
void inithashtab(){
    int i;
    for(i=0;i<HASHSIZE;i++)
        hashtab[i]=NULL;
}
//计算hash
unsigned int hash(char *s){    
    unsigned int h=0;
    for(;*s;s++){
        h=*s+h*N;
    }
    return h%HASHSIZE;
}
//找单词
node* lookup(char *n){
    unsigned int hi=hash(n);
    node* np=hashtab[hi];
    for( ;np!=NULL;np=np->next){
        if(!strcmp(np->word,n)&&np->word!=NULL&&n!=NULL){     //是否等
            return np;
        }
    }
    return NULL;
}
//存单词
char* save(char *o){  
    int l=strlen(o)+1;
    char *ns=(char*)malloc(l*sizeof(char));
    strcpy(ns,o);
    if(ns==NULL)
        return NULL;
    else
        return ns;
}
//获取 根据单词
char* get(char* word){
    node* n=lookup(word);
    if(n==NULL)
        return NULL;
    else
        return n->word;
}
//插入
int insert(char* word){  
    unsigned int hi;
    node* np;
    if((np=lookup(word))==NULL){       //先找
        hi=hash(word);                          //找不到 再分配
        np=(node*)malloc(sizeof(node));
        if(np==NULL)
            return 0;
        np->word=save(word);     //保存
        if(np->word==NULL) 
            return 0;
        np->next=hashtab[hi];  //插入的时候 如果发现冲突 就往链表里扔
        hashtab[hi]=np;
    }
    return 1;
}
//分割单词 找单词
int devide(char* word,int start){
    char *q;
    char a[BUFFER_SIZE]={},instead;
    size = strlen(word);
    while(*word&&size>0){
        instead = *word;
        a[start] = instead;
        //printf("a的值:%s
",a);
        q = a;
        if(get(a)){
            printf("找到啦~这个单词是:%s
",a);
            search[k++] = q;
            search[k++] = " ";
            word++;
            devide(word,0);          
            word--;
        }
        start++;
        word++;    
        if(strlen(word)==0){
            if(!get(q)){
                 search[--k]="";
                 search[--k]="";
            }
        }
    }
    if(k<=0){     //里面一个都没有
        return 0;
    }
    return 1;
}
 
int main(int argc, char **argv)
{
    FILE *fp;
    char str[N+1];
    int i = 0,n=0,s,count=0,flag=0,out_length;
    int c=0;
    if( (fp=fopen("yes.txt","r")) == NULL ){
        printf("Cannot open file, press enter to exit!
");
       return ;
    }
    while(fgets(str, N, fp) != NULL){
        words[n] = (char*)malloc(50*sizeof(char));   //每次动态开一个
        sscanf(str,"%[^:]",words[n]);    //匹配            
        //printf("第%d个单词是:%s
",n,words[n]);
        n++;
    }
    
    printf("统计单词数:%d
",n);
    printf("-----------------------------------------------------------------
");

    s = sizeof(words) / sizeof(words[0]);
    inithashtab();
    for(i=0;i<s;i++){   
        if(words[i]==NULL)
            break;
        insert(words[i]);
    }     

    //设置一个socket地址结构server_addr
    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(server_addr)); //把一段内存区的内容清零
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);//INADDR_ANY表示自动获取本机地址
    server_addr.sin_port = htons(PORT);
 
    //server_socket代表服务器socket
    int server_socket = socket(AF_INET,SOCK_STREAM,0);
    if( server_socket < 0)
    {
        printf("Create Socket Failed!");
        exit(1);
    }
     
    //把socket和socket地址结构联系起来
    if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)) <0)
    {
        printf("Server Bind Port : %d Failed!", PORT); 
        exit(1);   
    }
 
    //server_socket用于监听
    if ( listen(server_socket, LISTEN_COUNT) <0)
    {
        printf("Server Listen Failed!"); 
        exit(1);
    }

    while(1){//服务器端要一直运行
        printf("wating for client to connect!
");
        struct sockaddr_in client_addr;  
        socklen_t cliaddr_len = sizeof(client_addr);
        int new_server_socket = accept(server_socket,(struct sockaddr*)&client_addr,&cliaddr_len);
        if ( new_server_socket < 0)
        {
                printf("Server Accept Failed!
");                
                exit(1);
        }
        printf("wating for client to connect accept success!
");
        pid_t pid = fork();
        if(pid < 0){
            perror("fork error");
            exit(1);
        }else if(pid ==0){
            //close(server_socket);//关闭的是父进程的
            char buffer[BUFFER_SIZE];
            bzero(buffer, BUFFER_SIZE);
            while (recv(new_server_socket,buffer,BUFFER_SIZE,0)>0) 
            {        

                k = 0,size=0,out_length=0;            
                printf("收到:%s
",buffer);

                if(get(buffer)){    //索引判断是否存在
                    printf("Result -- %s !
",get(buffer));                    
                    if(send(new_server_socket,buffer,BUFFER_SIZE,0)<0){
                            printf("Server Send Failed
");
                            break;
                        }
                    continue;    
                }
                else
                    flag = devide(buffer,0);
                if(flag){
                    char output[BUFFER_SIZE]={};
                    printf("Result -- ");
                    for(i=0;i<k-1;i++){
                        printf("%s",search[i]);
                        strcat(output,search[i]);   //拼接 指针数组送不过去
                    }
                    out_length = strlen(output);
                    printf("
");
                    if(send(new_server_socket,output,out_length,0)<0){
                            printf("Server Send Failed
");
                            break;
                     }
                }
                else{        
                    printf("No Search ! 
");
                    char no[BUFFER_SIZE]={};
                    strcat(no,"No Find ! ");
                    int no_find_length = sizeof(no);
                    if(send(new_server_socket,no,no_find_length,0)<0)
                    {
                            printf("Server Send Failed
");
                            break;
                    }
                }
                printf("-----------------------------------------------------------------
");
                
            }
        }
        else if(pid >0){   //父进程
            close(new_server_socket);   
        }

    }
    close(server_socket);
    for(i=0;i<n;i++){
        free(words[i]);    //释放空间
    }
    fclose(fp);
    //关闭监听用的socket
    close(server_socket);
    return 0;
}
server_tcp_fork

tcp的服务器和客户端,服务器可以采用select这个函数句柄来实现多个客户端的调用(更推荐)

  1 #include <netinet/in.h>    // for sockaddr_in
  2 #include <sys/types.h>    // for socket
  3 #include <sys/socket.h>    // for socket
  4 #include <stdio.h>        
  5 #include <stdlib.h>        // for exit  
  6 #include <string.h>        // for bzero
  7 #include <time.h>
  8 #define PORT    7878
  9 #define BUFFER_SIZE 1024
 10 #define N 1024
 11  
 12 char *words[20000];
 13  
 14 int main(int argc, char **argv)
 15 {
 16     clock_t start, end;
 17     char str[N];
 18     int n=0;
 19     
 20     FILE *fp;
 21     if( (fp=fopen("key_string.txt","r")) == NULL ){
 22         printf("Cannot open file, press enter to exit!
");
 23        return ;
 24     }
 25     while(fgets(str, N, fp) != NULL){
 26         if(strlen(str)==N)
 27             continue;
 28         words[n] = (char*)malloc(1024*sizeof(char));   //每次动态开一个
 29         sscanf(str,"%[^
]",words[n]);    //匹配            
 30         n++;
 31     }
 32     n--;
 33     
 34     printf("key_string.txt的词数有:%d
",n);
 35     if (argc != 2)
 36     {
 37         printf("Please Input Server IP Address
");
 38         exit(1);
 39     } 
 40     
 41     //设置一个socket地址结构client_addr  
 42     struct sockaddr_in client_addr;
 43     bzero(&client_addr,sizeof(client_addr)); 
 44     client_addr.sin_family = AF_INET;    //internet协议族  PF_INET 也可以
 45     client_addr.sin_addr.s_addr = inet_addr(argv[1]);
 46     client_addr.sin_port = htons(0);    //0表示让系统自动分配一个空闲端口
 47 
 48     int client_socket = socket(AF_INET,SOCK_STREAM,0);
 49     if( client_socket < 0)
 50     {
 51         printf("Create Socket Failed!
");
 52         exit(1);
 53     }
 54 
 55         //设置一个socket地址结构server_addr,代表服务器的internet地址, 端口
 56     struct sockaddr_in server_addr;
 57     bzero(&server_addr,sizeof(server_addr));
 58     server_addr.sin_family = AF_INET;
 59     server_addr.sin_port = htons(PORT);
 60     int server_addr_length = sizeof(server_addr);
 61      //向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接 
 62     //三次握手
 63      if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0)
 64     {
 65         printf("Can Not Connect To %s!
",argv[1]);
 66         exit(1);
 67     }
 68 
 69     while(n!=-1){
 70         char input[BUFFER_SIZE]={};
 71       
 72        strcpy(input,words[n]);
 73         printf("-----------------------------------------------------------------
");
 74         printf("第%d的是:%s
",n,words[n]);
 75         char buffer[BUFFER_SIZE];
 76         bzero(buffer,BUFFER_SIZE);
 77        
 78         //向服务器发送buffer中的数据
 79          if(send(client_socket,input,BUFFER_SIZE,0)<0){
 80                     printf("Server Send Failed
");
 81                     break;
 82          }
 83         //从服务器接收数据到buffer中
 84         bzero(buffer,BUFFER_SIZE);
 85         int length = 0;
 86         length = recv(client_socket,buffer,BUFFER_SIZE,0);
 87         if(length < 0)
 88         {
 89             printf("Recieve Data From Server  Failed!
" );
 90             break;
 91         }
 92         printf("Search Result -- %s 
",buffer);
 93         bzero(buffer,BUFFER_SIZE); 
 94         printf("此时n的值为:%d
",n);
 95         n--;
 96         //关闭socket
 97 
 98     }
 99     fclose(fp);
100     close(client_socket);
101     return 0;
102 }
client_tcp_select
  1 #include <netinet/in.h>    // for sockaddr_in
  2 #include <sys/types.h>    // for socket
  3 #include <sys/socket.h>    // for socket
  4 #include <stdio.h>       
  5 #include <stdlib.h>        // for exit  
  6 #include <string.h>        // for bzero
  7 #include <sys/select.h>
  8 #include <sys/time.h>
  9 #include <unistd.h>
 10 #include <fcntl.h>
 11 
 12 #define PORT    7878
 13 #define LISTEN_COUNT 20
 14 #define BUFFER_SIZE 1024
 15 
 16 #define N 60
 17 #define HASHSIZE 2000000   //数组长度
 18 
 19 char* words[1600000];
 20 char* search[BUFFER_SIZE];
 21 int k = 0,size=0;//size用来判断当前移动单词的位置 
 22  
 23  typedef struct _node{
 24     char * word;
 25     struct _node *next;
 26 }node;
 27 
 28 static node* hashtab[HASHSIZE];
 29 //初始化 
 30 void inithashtab(){
 31     int i;
 32     for(i=0;i<HASHSIZE;i++)
 33         hashtab[i]=NULL;
 34 }
 35 //计算hash
 36 unsigned int hash(char *s){    
 37     unsigned int h=0;
 38     for(;*s;s++){
 39         h=*s+h*N;
 40     }
 41     return h%HASHSIZE;
 42 }
 43 //找单词
 44 node* lookup(char *n){
 45     unsigned int hi=hash(n);
 46     node* np=hashtab[hi];
 47     for( ;np!=NULL;np=np->next){
 48         if(!strcmp(np->word,n)&&np->word!=NULL&&n!=NULL){     //是否等
 49             return np;
 50         }
 51     }
 52     return NULL;
 53 }
 54 //存单词
 55 char* save(char *o){  
 56     int l=strlen(o)+1;
 57     char *ns=(char*)malloc(l*sizeof(char));
 58     strcpy(ns,o);
 59     if(ns==NULL)
 60         return NULL;
 61     else
 62         return ns;
 63 }
 64 //获取 根据单词
 65 char* get(char* word){
 66     node* n=lookup(word);
 67     if(n==NULL)
 68         return NULL;
 69     else
 70         return n->word;
 71 }
 72 //插入
 73 int insert(char* word){  
 74     unsigned int hi;
 75     node* np;
 76     if((np=lookup(word))==NULL){       //先找
 77         hi=hash(word);                          //找不到 再分配
 78         np=(node*)malloc(sizeof(node));
 79         if(np==NULL)
 80             return 0;
 81         np->word=save(word);     //保存
 82         if(np->word==NULL) 
 83             return 0;
 84         np->next=hashtab[hi];  //插入的时候 如果发现冲突 就往链表里扔
 85         hashtab[hi]=np;
 86     }
 87     return 1;
 88 }
 89 //分割单词 找单词
 90 int devide(char* word,int start){
 91     char *q;
 92     char a[BUFFER_SIZE]={},instead;
 93     size = strlen(word);
 94     while(*word&&size>0){
 95         instead = *word;
 96         a[start] = instead;
 97         //printf("a的值:%s
",a);
 98         q = a;
 99         if(get(a)){
100             printf("找到啦~这个单词是:%s
",a);
101             search[k++] = q;
102             search[k++] = " ";
103             word++;
104             devide(word,0);          
105             word--;
106         }
107         start++;
108         word++;    
109         if(strlen(word)==0){
110             if(!get(q)){
111                  search[--k]="";
112                  search[--k]="";
113             }
114         }
115     }
116     if(k<=0){     //里面一个都没有
117         return 0;
118     }
119     return 1;
120 }
121 
122 int mz_ipv4_tcp_create_socket(void)
123 {
124     int listenfd, sockfd, opt = 1;
125     struct sockaddr_in server, client;
126     socklen_t len;
127     listenfd = socket(AF_INET, SOCK_STREAM, 0);
128 
129     if(listenfd < 0){
130         perror("Create socket fail.");
131         return -1;
132     } 
133 
134     bzero(&server, sizeof(server));
135     server.sin_family = AF_INET;
136     server.sin_port   = htons(PORT);
137     server.sin_addr.s_addr  = htonl(INADDR_ANY);
138     
139     len = sizeof(struct sockaddr);
140     if(bind(listenfd, (struct sockaddr *)&server, len)<0){
141               perror("bind error");
142         return -1;
143     }
144       
145     listen(listenfd, LISTEN_COUNT);
146 
147     return listenfd;
148 }
149 
150 
151 int main(int argc, char *argv[])
152 {
153     FILE *fp;
154     char str[N+1];
155     int j = 0,n=0,s;
156     int c=0;
157     
158     if( (fp=fopen("yes.txt","r")) == NULL ){
159         printf("Cannot open file, press enter to exit!
");
160        return ;
161     }
162     while(fgets(str, N, fp) != NULL){
163         words[n] = (char*)malloc(50*sizeof(char));   //每次动态开一个
164         sscanf(str,"%[^:]",words[n]);    //匹配            
165         //printf("第%d个单词是:%s
",n,words[n]);
166         n++;
167     }
168     
169     printf("统计单词数:%d
",n);
170     printf("-----------------------------------------------------------------
");
171     s = sizeof(words) / sizeof(words[0]);
172     inithashtab();
173     for(j=0;j<s;j++){   
174         if(words[j]==NULL)
175             break;
176         insert(words[j]);
177     }
178     
179     int listenfd, sockfd;
180     struct sockaddr_in server, client;
181     int bytes =0 ;
182     fd_set global_rdfs,current_rdfs;    
183     int maxfd;    
184     int i;
185     int z;
186     int out_length,flag;
187     char buffer[BUFFER_SIZE];
188 
189     socklen_t cli_len = sizeof(struct sockaddr_in);
190 
191     listenfd = mz_ipv4_tcp_create_socket();
192     FD_ZERO(&global_rdfs);
193     FD_SET(listenfd, &global_rdfs);
194     maxfd = listenfd;
195     while(1){        
196         k=0,size=0,out_length=0;    
197         current_rdfs = global_rdfs;
198         if(select(maxfd + 1, &current_rdfs, NULL, NULL, NULL)<0){
199             perror("select error.
");
200             return -1;
201         }
202         for(i = 0; i <= maxfd; i++){
203 
204             if(FD_ISSET(i, &current_rdfs)){
205                 if(listenfd == i){
206                     if((sockfd = accept(listenfd, (struct sockaddr*)&client, &cli_len))<0){
207                         perror("accept error.
");
208                         return -1;
209                     }
210                     FD_CLR(i, &current_rdfs);
211                     maxfd = maxfd > sockfd ? maxfd :sockfd;
212                     FD_SET(sockfd, &global_rdfs);
213                 }
214                 else{
215                     bzero(buffer,BUFFER_SIZE);
216                     bytes = recv(i, buffer, BUFFER_SIZE, 0);
217                     if(bytes < 0){
218                         perror("recv error.
");
219                         return -1;
220                     }
221                     if(bytes == 0){
222                         FD_CLR(i, &global_rdfs);
223                         close(i);
224                         continue;
225                     }
226                     printf("收到的buf:%s
", buffer);
227                 //    send(i, buffer, strlen(buffer), 0);    
228                     if(get(buffer)){    //索引判断是否存在
229                         printf("Result -- %s !
",get(buffer));    
230                         printf("----------------------------------------------
");                        
231                         if(send(i,buffer,BUFFER_SIZE,0)<0){
232                                 printf("Server Send Failed
");
233                                 break;
234                             }
235                         continue;    
236                     }
237                     else{
238                         flag = devide(buffer,0);         //进行分词
239                         if(flag){
240                             char output[BUFFER_SIZE];
241                             bzero(output,BUFFER_SIZE);
242                             printf("Result -- ");
243                             for(z=0;z<k-1;z++){
244                                 printf("%s",search[z]);
245                                 strcat(output,search[z]);   //拼接 指针数组送不过去
246                             }
247                             out_length = strlen(output);
248                             printf("
");
249                             printf("----------------------------------------------
");    
250                             if(send(i,output,out_length,0)<0){
251                                     printf("Server Send Failed
");
252                                     break;
253                              }
254                         }
255                         else{        
256                             printf("No Search ! 
");
257                             printf("----------------------------------------------
");    
258                             char no[BUFFER_SIZE];
259                             bzero(no,BUFFER_SIZE);
260                             strcat(no,"No Find ! ");
261                             int no_find_length = sizeof(no);
262                             if(send(i,no,no_find_length,0)<0)
263                             {
264                                     printf("Server Send Failed
");
265                                     break;
266                             }
267                         }
268                     }
269                 }
270 
271             }
272         
273         }
274     }
275     close(listenfd);
276 return 0;
277 
278 }
server_tcp_select

以上是自己花了一段时间写的测试程序,学习了ruby的hash,以及用linux-c写的socket通讯,发现还蛮好玩的,继续努力。

第一次写博客,排版可能有点丑。      

转载于:https://www.cnblogs.com/zhe-hello/p/8607649.html

原文地址:https://www.cnblogs.com/twodog/p/12137313.html