linux c做服务端使用多线程接收图片并且将图片写入数据库
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/stat.h>//包含文件的全部结构,属性
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<error.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
#include<sys/time.h>
#include<sqlite3.h> #define SER_PORT 1900
#define MAX_LEN 256
#define FILENAME_LENGTH 32 int listensd,connectsd;
char buf[MAX_LEN] = " ";
char flag[MAX_LEN]=" ";
pthread_t thread[];
int threadnum=;
sqlite3 *db=;
char * pErrMsg;//保存返回数据库错误 //数据库查询回调函数定义
int select_callback(void * data, int col_count, char ** col_values, char ** col_Name)
{
// 每条记录回调一次该函数,有多少条就回调多少次
int i;
for( i=; i < col_count; i++){
printf( "%s = %s\n", col_Name[i], col_values[i] == ? "NULL" : col_values[i] );
printf("\n");
} return ;
} //次回调函数用于查询数据库的所有图片并且把每一项的url解析并且发送给客户端
int select_callback_send(void *data,int col_count,char **col_values,char** col_name){
int i;
FILE *fp=NULL;
int len_send;
char *buf_time=" ";
for(i=;i<col_count;i++){
printf("%s=%s=n",col_name[i],col_values[i]==?"NULL":col_values[i]);
//发送插入时间
if(strcmp("[InsertTime]",col_name[i])==){
buf_time=col_name[i];
if(write(connectsd,buf_time,sizeof(buf_time))<){
perror("buf_time write error:\n");
}
//发送图片
if(strcmp("[url]",col_name[i])==){
if((fp=fopen(col_name[i],"ab"))==NULL){
perror("file open error");
}else{
while(!feof(fp)){
len_send=fread(buf,,MAX_LEN,fp);
if(len_send!=write(connectsd,buf,len_send)){
perror("write");
}
}
}
printf("图片%s发送成功!",col_name[i]);
}
}
} //线程函数定义
int *threadf(){
int con_copy=connectsd;
int len;
FILE *fp=NULL;
FILE *fp1=NULL;
int status=;
char filename[FILENAME_LENGTH]=" ";
char sql[]=" ";//这里使用数组或者是字符指针都是一样的到时候传入的都是名字即首地址
bzero(flag,sizeof(flag));
read(con_copy,flag,MAX_LEN);
printf("flag:");
fputs(flag,stdout);
printf("\n");
//服务端接收图片
// bzero(flag,sizeof(flag));
bzero(buf,sizeof(buf));
if(strcmp(flag,"send\n")==){
snprintf(filename,FILENAME_LENGTH,"%d.jpg",threadnum);
if((fp=fopen(filename,"ab"))==NULL){
perror("File open");
//close(listensd);
exit();
}
while(){
len=read(con_copy,buf,MAX_LEN);
if(len<){//加上该错误判断就能保证在出错时能正确退出
perror("read");
exit();
}
if(len==){
break;
}
fwrite(buf,,len,fp);
}
//写入数据库
snprintf(sql,,"insert into pic([picId],[url]) values(null,'%s')",filename);
if(sqlite3_exec(db,sql,,,&pErrMsg)!=SQLITE_OK){
fprintf(stderr,"insert sql error:%s\n",pErrMsg);
sqlite3_free(pErrMsg);
}else{
printf("插入数据成功\n");
//每一次插入成功都使用查询显示当前的数据库状态
printf("开始查询数据:\n");
if(sqlite3_exec( db, "select * from pic;", select_callback, , &pErrMsg)!=SQLITE_OK){
fprintf(stderr, "select SQL error: %s\n", pErrMsg);
}else{
printf("查询成功! \n");
}
}
printf("the pic %d is accept suc!\n",threadnum);
close(con_copy);
fclose(fp);
return ;
//服务端发送图片(先从数据库查询可用数据,找到相应的url依次打开并且发送给客户端)
}else if(strcmp(flag,"rec\n")==){
if( ( fp1 = fopen("client.jpg","rb") ) == NULL )
{
perror("File open");
//close(listensd);
exit();
}
while( !feof(fp1) )
{
len = fread(buf,,MAX_LEN,fp1);//从文件fq中读取MAX_LEN个字段每个字段长度为1并且给buf
if( len != write(con_copy,buf,len) )
{
perror("write");
break;
}
}
close(con_copy);
//close(listensd);
fclose(fp1);
return ;
}else{
return ;
} // if(!mkdir(filename,0777)){
// printf("创建目录失败");
// }
// snprintf(filename,FILENAME_LENGTH,"//1.jpg"); // if(SQLITE_OK!=sqlite3_open("pic.db",&db)){
// fprintf(stderr,"无法连接数据库:%s",sqlite3_errmsg(db));
// exit(1);
// }
// if(SQLITE_OK!=sqlite3_exec(db,"insert into pic(url) values("test.jpg")",0,0,&pErrMsg));
// {
// fprintf(stderr,"无法插入数据:%s",sqlite3_errmsg(db));
// exit(1);
// }
} //初始化数据库,包括创建库和表
void initDb(){
char * createtablesql=
"create table pic([picId] integer PRIMARY KEY AUTOINCREMENT, [InsertTime] TimeStamp NOT NULL DEFAULT (datetime('now','localtime')), [url] varchar(20))";
if(sqlite3_open("pic.db",&db)!=SQLITE_OK){
fprintf(stderr,"无法打开数据库:%s",sqlite3_errmsg(db));
}else{
printf("数据库创建成功!\n");
}
if(sqlite3_exec(db,createtablesql,,,&pErrMsg)!=SQLITE_OK){
fprintf(stderr, "无法创建数据表:%s\n", pErrMsg);
}else{
printf("建表成功!\n");
}
} int main(int argc,char **argv)
{
struct sockaddr_in server;
struct sockaddr_in client;
FILE *fp;
int opt = ;
if( ( listensd = socket(AF_INET,SOCK_STREAM,) ) == - )
{
perror("socket");
exit();
}
setsockopt(listensd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(SER_PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
if( bind(listensd,(struct sockaddr *)&server,sizeof(server)) < )
{
perror("Bind");
close(listensd);
exit();
}
if( listen(listensd,) == - )
{
perror("listen");
close(listensd);
exit();
}
initDb();
while( )
{
int rn ;
int sin_len = sizeof(client);
//accept为阻塞,一直等到有客户端连接到时候才会进行并且往下执行,多线程中每一次新的线程建立的时候都是一个新的连接
if( (connectsd = accept(listensd,(struct sockaddr *)&client,&sin_len)) < )
{
perror("accept");
continue;
}
printf("新连接建立!");
if(threadnum<){
pthread_create(&thread[threadnum],NULL,threadf,NULL);
pthread_detach(&thread[threadnum]);//分离子线程和主线程
printf("客户端%d已经开始传输数据!\n",threadnum);
threadnum++;
}else{
printf("threadsize over!\n");
close(listensd);
break;
}
}
// int i=0;
// for(i;i<threadnum;i++){//等待所有已经创建的线程结束后才结束该进程
// pthread_join(thread[i],NULL);
// printf("线程%d已经加入等待\n",i);
// }
close(listensd);
return ;
}
linux c做服务端使用多线程接收图片并且将图片写入数据库的更多相关文章
- 最全Linux搭建SVN服务端教程
文章首推 支付宝接口对接 高德地图调用 验证码登录 QQ邮箱登录 今日主题:Linux搭建SVN服务端 简介 相信程序员对SVN还是不陌生的,虽然现在用Git比较多,但是SVN也是用的,SVN可以做代 ...
- PHP-Socket服务端客户端发送接收通信实例详解
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://fighter.blog.51cto.com/1318618/1533957 So ...
- android上传图片、视频、文件,服务端使用wcf接收
最近一直在搞android上传图片.视频.文件,服务端使用wcf接收,本文对调试中的遇到的问题进行记录. 首先android上传一些小图片是比较容易的一天下来差不多就能调试出来,但是上传一些大的文件时 ...
- 利用webuploader插件上传图片文件,完整前端示例demo,服务端使用SpringMVC接收
利用WebUploader插件上传图片文件完整前端示例demo,服务端使用SpringMVC接收 Webuploader简介 WebUploader是由Baidu WebFE(FEX)团队开发的一 ...
- Linux 部署 iSCSI 服务端
Linux 部署 iSCSI 服务端 服务端实验环境 iSCSI-server :RHEL8 IP:192.168.121.10 一.服务端安装 target 服务和 targetcli 命令行工具 ...
- .NET应用架构设计—服务端开发多线程使用小结(多线程使用常识)
有一段时间没有更新博客了,最近半年都在着写书<.NET框架设计—大型企业级框架设计艺术>,很高兴这本书将于今年的10月份由图灵出版社出版,有关本书的具体介绍等书要出版的时候我在另写一篇文行 ...
- SSE技术详解:使用 HTTP 做服务端数据推送应用的技术
SSE ( Server-sent Events )是 WebSocket 的一种轻量代替方案,使用 HTTP 协议. 严格地说,HTTP 协议是没有办法做服务器推送的,但是当服务器向客户端声明接下来 ...
- Linux下多进程服务端客户端模型二(粘包问题与一种解决方法)
一.Linux发送网络消息的过程 (1) 应用程序调用write()将消息发送到内核中 ( 2)内核中的缓存达到了固定长度数据后,一般是SO_SNDBUF,将发送到TCP协议层 (3)IP层从TCP层 ...
- Linux下多进程服务端客户端模型一(单进程与多进程模型)
本文将会简单介绍Linux下如何利用C库函数与系统调用编写一个完整的.初级可用的C-S模型. 一.基本模型: 1.1 首先服务器调用socket()函数建立一个套接字,然后bind()端口,开始l ...
随机推荐
- Windows映射网络驱动器提示错误
问题描述:Windows映射网络驱动器的时候,提示文件和打印机共享资源处于联机状态未对连接尝试检测到做出响应 解决方法:不同情况可能不一样,我的原因是,映射的Linux,防火墙处于开启状态,关闭了就可 ...
- asp.net FileUpload上传文件夹并检测所有子文件
1.在FileUpload控件添加一个属性 webkitdirectory=""就可以上传文件夹了 <asp:FileUpload ID="FileUpload1& ...
- CentOS初使用命令总结
最近买了一台aliyun(ECS服务器)用来学习使用,初次使用难免要走弯路.遇到一些问题好长时间解决不了,结果经人指点豁然开朗.于是乎,总结了一些新生上路经验. 首先要解决的问题是:通过PuTTY.S ...
- Spring学习笔记:Spring概述,第一个IoC依赖注入案例
一.Spring的优点 企业及系统: 1.大规模:用户数量多.数据规模大.功能众多 2.性能和安全要求高 3.业务复杂 4.灵活应变 Java技术:高入侵式依赖EJB技术框架-->Spring框 ...
- Python pip windows安装
参考页面: [1] : https://pip.pypa.io/en/latest/installing.html [2] : http://stackoverflow.com/questions/4 ...
- Git和GitHub在线学习资源整理(转)
原文地址:http://blog.csdn.net/duqi_2009/article/details/12646711 电子书 GotGitHub Git Workflow 文章 GitHub Fu ...
- scss-变量分隔符
scss的变量名可以与css中的属性名和选择器名称相同,包括中划线和下划线. 在使用中划线还是下划线来进行变量分隔完全根据个人喜好. scss完全兼容这两种写法,也就是说scss认为中划线和下划线是完 ...
- 编译时提示软件包 javax.servlet.http 不存在 import javax.servlet.http.HttpServletRequest;
编译时错误:软件包 javax.servlet.http 不存在import javax.servlet.http.HttpServletRequest; 解决办法:把servlet-api.jar加 ...
- 转:一个优秀windows C++程序员的知识体系
转自:http://www.cppblog.com/weiym/archive/2012/06/10/178287.html.根据自身的经历,觉得作者总结的很好. 思考一个优秀windows C++ ...
- Linux 配置 ss
Linux 配置 Shadowsocks 标签(空格分隔): ss VPS 1.首先安装 sudo pip install shadowsocks 2.然后在指定位置新建shadowsocks.jso ...