自写项目——实现tesseract-ocr功能_初步socket实现 在安装好tesseract-ocr后,已经能够在本机上初步识别一些文字,但要把其搭在服务器上,就需要一些文件传输,这里采用socket编程,实现服务器与客户端的文件传输。 我做好了服务端,和客户端: 客户端上传
自写项目——实现tesseract-ocr功能_初步socket实现
在安装好tesseract-ocr后,已经能够在本机上初步识别一些文字,但要把其搭在服务器上,就需要一些文件传输,这里采用socket编程,实现服务器与客户端的文件传输。
我做好了服务端,和客户端:
客户端上传图片文件到服务端,并选择要识别的语言,并接受到服务端传回的结果。
服务端安装了tesseract-ocr,接受客户端传送的图片文件,在服务端进行识别,并把结果传送到客户端。
这就是其大概的思路,下面上代码(已经加上注释!linux下验证通过):
客户端(client):
#include <stdio.h> #include <pthread.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <signal.h> #define BUFFER_SIZE 1024 //准备工作 int sockfd;// char* IP = "192.168.30.3";//该地址请写测试服务器的IP,本机IP,回送地 short PORT = 10222;//端口号 typedef struct sockaddr SA;//类型转换 char filename[100];//客户端昵称 char langeuage[100]; //启动客户端,连接服务器 void init() { printf("OCR客户端开始启动\n"); sockfd = socket(AF_INET,SOCK_STREAM,0);//启动socket struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = inet_addr(IP); if(connect(sockfd,(SA*)&addr,sizeof(addr))==-1){//向服务器请求建立链接 perror("无法连接到服务器"); printf("客户端启动失败\n"); exit(-1); } printf("客户端启动成功\n"); } //开始通信 void start() { //发送消息 //发消息之前,启动一个线程,用来接受服务器发送过来的消息 // pthread_t pid; // pthread_create(&pid,0,recv_thread,0); // 打开文件并读取文件数据 char buffer[BUFFER_SIZE]; int file_size=0; int sum=0; FILE *fp = fopen(filename, "r"); fseek(fp, 0, SEEK_END); file_size=ftell(fp);//得到文件大小 // printf("file_size=%d",file_size); send(sockfd,&file_size,sizeof(int),0);// 把文件大小数据发送 fseek(fp, 0, SEEK_SET); if(NULL == fp) { printf("File:%s Not Found\n", filename); } else { bzero(buffer, BUFFER_SIZE); //清空buffer int length = 0; // 每读取一段数据,便将其发送给客户端,循环直到文件读完为止 while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0) { if(send(sockfd, buffer, length, 0) < 0)//发送失败退出 { printf("Send File:%s Failed./n", filename); return ; } bzero(buffer, BUFFER_SIZE); } // 关闭文件 fclose(fp); /****************用户提示区***************/ printf("******************************\n"); printf("File:%s Transfer Successful!\n", filename); printf("******************************\n\n"); printf("系统正在识别,请稍后......\n"); printf("这可能需要一段时间........\n\n"); /*****************************************/ fp = fopen("result.txt", "wt"); //printf("flag\n\n"); if(NULL == fp) { printf("File:\t%s Can Not Open To Write\n", "result.txt"); exit(1); } // 从服务器接收数据到buffer中 // 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止 bzero(buffer, BUFFER_SIZE); while((length = recv(sockfd, buffer, BUFFER_SIZE, 0)) > 0) { sum+=length; printf("->已接受%d kb\n",sum); //printf("length=%d\n",length); if(fwrite(buffer, sizeof(char), length, fp)<0)//写入文件中 { printf("Write file result.txt Failed."); return ; } bzero(buffer, BUFFER_SIZE); } //若服务端解析图片错误,就不会发送完整的result.txt 则输出提示信息。 printf("\n******************************\n"); if(sum>3) printf("Receive File:\t%s From Server IP Successful!\n", filename); else printf("The image is wrong!\n"); printf("******************************\n"); printf("\n文档已成功接受!请在本目录下的result.txt下查看!\n"); // 接收成功后,关闭文件,关闭socket fclose(fp); } close(sockfd);//关闭socket } void sig_close() { //关闭客户端的描述符 close(sockfd); exit(0); } int main() { int type; signal(SIGINT,sig_close);//关闭CTRL+C init();//启动并连接服务器 printf("\n请输入文件名:"); scanf("%s",filename); printf("语言类型对应编号:\n"); printf("English :1\t中文简体:2\n"); printf("中文繁体:3\tFrancd :4\n\n"); printf("请输入要识别的语言类型(请务必填对应的编号):"); scanf("%d",&type); switch(type) { case 1: strcpy(langeuage,"eng"); break; case 2: strcpy(langeuage,"chi_sim"); break; case 3: strcpy(langeuage,"chi_tra"); break; case 4: strcpy(langeuage,"fra"); break; default: strcpy(langeuage,"eng"); } send(sockfd,filename,sizeof(filename),0);//把图片名字传到服务器 send(sockfd,langeuage,sizeof(langeuage),0);//把语言类型传到服务器 start();//开始与服务器进行通信。 return 0; }
服务端(server):
#include <stdio.h> #include <pthread.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <signal.h> #define BUFFER_SIZE 1024 char buffer[BUFFER_SIZE]; //准备工作 int sockfd;// char* IP = "192.168.30.3";//服务器IP short PORT = 10222;//端口号 typedef struct sockaddr SA;//类型转换 //初始化服务器的网络,创建socket void init() { printf("OCR服务器开始启动..\n"); sockfd = socket(AF_INET,SOCK_STREAM,0);//启动socket if(sockfd == -1){ perror("创建socket失败"); printf("服务器启动失败\n"); exit(-1); } //准备网络通信地址 struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = inet_addr(IP); if(bind(sockfd,(SA*)&addr,sizeof(addr))==-1){//绑定服务器 perror("绑定失败"); printf("服务器启动失败\n"); exit(-1); } printf("成功绑定\n"); //设置监听 if(listen(sockfd,10)==-1){ perror("设置监听失败"); printf("服务器启动失败\n"); exit(-1); } printf("设置监听成功\n"); printf("初始化服务器成功\n"); //等待客户端链接,放到另一个函数中 } void* service_thread(void* p) { int sum=0; int file_size=0; int fd = *(int*)p; //拿到标记客户端的sockfd //printf("pthread=%d\n",fd);//输出测试 char filename[100] ={0}; int length = 0; char shell_order[200]={0}; char langeuage[100]; recv(fd,filename,sizeof(filename),0); //得到文件名字 recv(fd,langeuage,sizeof(langeuage),0); //得到语言类型 recv(fd,&file_size,sizeof(int),0); //得到文件大小 /******************************从服务端接受文件*********************************/ FILE *fp = fopen(filename, "wt"); if(NULL == fp) { printf("File:\t%s Can Not Open To Write\n", filename); exit(1); } // 从服务器接收数据到buffer中 // 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止 bzero(buffer, BUFFER_SIZE); //printf("file_size=%d\n",file_size); while((length = recv(fd, buffer, BUFFER_SIZE, 0)) > 0)//接受文件 { //printf("length=%d\n",length); sum+=length; if(file_size==sum) break; if(fwrite(buffer, sizeof(char), length, fp)<0)//写文件 { printf("Write %s File Failed!",filename); return NULL; } bzero(buffer, BUFFER_SIZE); } // 接收成功后,关闭文件,关闭socket printf("Receive File:\t%s From Server IP Successful!\n", filename); fclose(fp); /***********************************************************/ /**************************调用shell命令行语句*********************************/ sprintf(shell_order,"tesseract %s result -l %s",filename,langeuage); system(shell_order); /******************************************************************************/ /************************向客户端发送文件****************************/ fp=fopen("result.txt","r"); if(NULL == fp) printf("File:%s Not Found\n","result.txt"); else { bzero(buffer,BUFFER_SIZE); while((length = fread(buffer,sizeof(char),BUFFER_SIZE,fp)) > 0) { if(send(fd,buffer,length,0)<0) { printf("Send File: %s Failed",filename); return NULL; } bzero(buffer, BUFFER_SIZE); } // 关闭文件 fclose(fp); printf("File:%s Transfer Successful!\n", "result.txt"); } /*******************************************************/ close(fd);//关闭socket } //等待客户端的连接,启动服务器的服务 void service() { printf("服务器开始服务\n"); while(1)//一直循环,等待客户端链接 { struct sockaddr_in fromaddr; socklen_t len = sizeof(fromaddr); int fd = accept(sockfd,(SA*)&fromaddr,&len); if(fd == -1) { printf("客户端链接出错\n"); continue;//继续循环,处理连接 } //如果客户端成功连接上 printf("fd=%d\n",fd);//测试 //启动线程 pthread_t pid; pthread_create(&pid,0,service_thread,&fd); } } void signal_close(int signal_num){ //关闭服务器前 关闭服务器的socket close(sockfd); printf("服务器已经关闭\n"); exit(1); } int main() { signal(SIGINT,signal_close);//退出CTRL+C init();//初始化服务器 service();//服务器开始运行 return 0; }
这里需要注意,服务端搭到服务器上,而且保证服务器已经安装了tesseract-ocr,安装教程在这里:http://blog.csdn.net/chudongfang2015/article/details/51866379
如果需要在本机测试,只需把服务端和客户端的IP都改为:127.0.0.1(本地环回)