#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做服务端使用多线程接收图片并且将图片写入数据库的更多相关文章

  1. 最全Linux搭建SVN服务端教程

    文章首推 支付宝接口对接 高德地图调用 验证码登录 QQ邮箱登录 今日主题:Linux搭建SVN服务端 简介 相信程序员对SVN还是不陌生的,虽然现在用Git比较多,但是SVN也是用的,SVN可以做代 ...

  2. PHP-Socket服务端客户端发送接收通信实例详解

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://fighter.blog.51cto.com/1318618/1533957 So ...

  3. android上传图片、视频、文件,服务端使用wcf接收

    最近一直在搞android上传图片.视频.文件,服务端使用wcf接收,本文对调试中的遇到的问题进行记录. 首先android上传一些小图片是比较容易的一天下来差不多就能调试出来,但是上传一些大的文件时 ...

  4. 利用webuploader插件上传图片文件,完整前端示例demo,服务端使用SpringMVC接收

    利用WebUploader插件上传图片文件完整前端示例demo,服务端使用SpringMVC接收 Webuploader简介   WebUploader是由Baidu WebFE(FEX)团队开发的一 ...

  5. Linux 部署 iSCSI 服务端

    Linux 部署 iSCSI 服务端 服务端实验环境 iSCSI-server :RHEL8 IP:192.168.121.10 一.服务端安装 target 服务和 targetcli 命令行工具 ...

  6. .NET应用架构设计—服务端开发多线程使用小结(多线程使用常识)

    有一段时间没有更新博客了,最近半年都在着写书<.NET框架设计—大型企业级框架设计艺术>,很高兴这本书将于今年的10月份由图灵出版社出版,有关本书的具体介绍等书要出版的时候我在另写一篇文行 ...

  7. SSE技术详解:使用 HTTP 做服务端数据推送应用的技术

    SSE ( Server-sent Events )是 WebSocket 的一种轻量代替方案,使用 HTTP 协议. 严格地说,HTTP 协议是没有办法做服务器推送的,但是当服务器向客户端声明接下来 ...

  8. Linux下多进程服务端客户端模型二(粘包问题与一种解决方法)

    一.Linux发送网络消息的过程 (1) 应用程序调用write()将消息发送到内核中 ( 2)内核中的缓存达到了固定长度数据后,一般是SO_SNDBUF,将发送到TCP协议层 (3)IP层从TCP层 ...

  9. Linux下多进程服务端客户端模型一(单进程与多进程模型)

    本文将会简单介绍Linux下如何利用C库函数与系统调用编写一个完整的.初级可用的C-S模型. 一.基本模型: 1.1   首先服务器调用socket()函数建立一个套接字,然后bind()端口,开始l ...

随机推荐

  1. Beyond Compare 4试用期已过

    Beyond Compare 很好用,但是只有一段时间的试用时间,当试用期过了之后就提示不能试用了 怎么办呢? 我在网上找到了两个方法: 1.直接用注册码(来自:https://blog.csdn.n ...

  2. Java学习第十八天

    1:Map(掌握) (1)将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值. (2)Map和Collection的区别? A:Map 存储的是键值对形式的元素,键唯一,值可以重 ...

  3. C# 如何提取SaveFileDialog的保存路径?

    public TestOne() { InitializeComponent(); SaveFileDialog();//调用打开SaveFileDialog 保存对话框 } #region 保存对话 ...

  4. MVC类库视图在UI使用方法

    在类库中固定文件:Controller Views  引用一下两个程序集(类库和UI项目都需要引用)(似乎只需要引用mvc的,build似乎在引用文件中不见了?有空测试一下) 如此方式,一个登录需要是 ...

  5. 位运算(6)——Number Complement

    Given a positive integer, output its complement number. The complement strategy is to flip the bits ...

  6. ubuntu 14.04 64bit 安装 oracle 11g r2

    参考文章:http://tutorialforlinux.com/2016/03/09/how-to-install-oracle-11g-r2-database-on-ubuntu-14-04-tr ...

  7. PAT 1070 Mooncake

    题目意思能搞成这样我也是服了这个女人了 #include <cstdio> #include <cstdlib> #include <vector> #includ ...

  8. scss-字符串连接符

    + 运算可用于连接字符串: // SCSS p { cursor: e + -resize; } // 编译后的 CSS 样式 p { cursor: e-resize; } 请注意,如果带引号的字符 ...

  9. JavaScript Callback 回调函数

    JavaScript callback回调函数 你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货.在这 ...

  10. 视觉库—OpenCV

    视频会议软件的视频质量除了与外置设备.编码器相关外,还与视频的后处理技术相关,视频图像通过后处理技术,如图像增强.图像去噪等,图像质量会得到主观上较大的提高.而我们通常的视频后处理技术会采用开源的项目 ...