#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include "debug.h"
#include "utils.h"
#include "ipmsg.h"
#include "sys_info.h"
#include "comm.h"
#include "user_manage.h"
#include "com_pthread.h"
#include "file_trans.h"
static PFILEINFO sendFileList = NULL;
static pthread_mutex_t sendFileMutex = PTHREAD_MUTEX_INITIALIZER;
#define LOCK_SENDFILE(a) \
pthread_mutex_lock(&sendFileMutex); \
{ \
a; \
} \
pthread_mutex_unlock(&sendFileMutex);
typedef struct _cliInfo_t {
int connfd;
struct sockaddr_in address;
} CLIENTINFO, *PCLIENTINFO;
typedef struct request_file_info_t {
unsigned long packageNo;
unsigned long fileNo;
unsigned long offset;
}REQFILEINFO, *PREQFILEINFO;
static int parseRawRequestFileMsg(char *req, PREQFILEINFO fileInfo)
{
char *StopAt;
fileInfo->packageNo = strtoul(req, &StopAt, 16);
if((StopAt <= req) || (*StopAt != ':'))
return -1;
req = StopAt + 1;
fileInfo->fileNo = strtoul(req, &StopAt, 16);
if(StopAt <= req)
return -1;
if(*StopAt == ':')
fileInfo->offset = strtoul(StopAt + 1, NULL, 16);
else
fileInfo->offset = 0;
return 0;
}
static int getFileNumberOfUsr(PUSER_INFO usr)
{
int count = 0;
PFILEINFO file;
LOCK_SENDFILE(
file = sendFileList;
while(file)
{
if(file->usr == usr)
count++;
file = file->next;
}
);
return count;
}
static PFILEINFO getFileInfo(PUSER_INFO usr, unsigned long int packageNo, unsigned int fileNo)
{
PFILEINFO ret = NULL;
PFILEINFO file;
LOCK_SENDFILE(
file = sendFileList;
while(file)
{
if((file->usr == usr) && (file->packageNo == packageNo) && (file->FileNo == fileNo))
{
ret = file;
break;
}
file = file->next;
}
);
return ret;
}
static int uploadFile(int sockfd, PFILEINFO file)
{
unsigned char buf[4096];
int len;
FILE *fp = fopen(file->path, "rb");
int totSize = 0;
if(fp == NULL)
return -1;
while((len = fread(buf, 1, sizeof(buf), fp)) > 0)
{
write(sockfd, buf, len);
totSize += len;
}
fclose(fp);
PRINTF("file sending over!\n");
DBUG(PRINTF("totSize = %d\n", totSize));
return 0;
}
static int uploadFilePack(const char *fullpath, const struct stat *sb, int flag, void *arg)
{
FILE *tcpOut = fdopen((int)arg, "w");
unsigned long fileSize;
char buf[256];
A_PRINTF("fullpath = %s, flag = %d\n", fullpath, flag);
if(flag == FTW_INVALID)
return -1;
switch(flag)
{
case FTW_INVALID:
return -1;
case FTW_FILE:
PRINTF(" This is a file!\n");
fileSize = sb->st_size;
sprintf(&buf[5], "%s:%lx:%x:", getFileName(fullpath), fileSize, IPMSG_FILE_REGULAR);
break;
case FTW_FOLDER:
PRINTF(" This is a folder!\n");
fileSize = 0;
sprintf(&buf[5], "%s:0:%x:", getFileName(fullpath), IPMSG_FILE_DIR);
break;
case FTW_RETPARENT:
PRINTF(" This is return parent!\n");
fileSize = 0;
sprintf(&buf[5], ".:0:%x:", IPMSG_FILE_RETPARENT);
break;
}
sprintf(buf, "%04x", strlen(&buf[5]) + 5);
buf[4] = ':';
PRINTF("the buf is [%s]\n", buf);
fwrite(buf, 1, strlen(buf), tcpOut);
PRINTF(" start to sending file content...\n");
while(fileSize > 0)
{
char sendBuf[1024];
int len;
FILE *fp = fopen(fullpath, "rb");
if(fp == NULL)
break;
PRINTF("fp = %p\n", fp);
do {
len = fread(sendBuf, 1, sizeof(sendBuf), fp);
if(len > 0)
fwrite(sendBuf, 1, len, tcpOut);
} while(len > 0);
fclose(fp);
break;
}
fflush(tcpOut);
return 0;
}
static int uploadFolder(int sockfd, PFILEINFO file)
{
int ret;
A_PRINTF("file->path = %s\n", file->path);
ret = fileTreeWalk(file->path, uploadFilePack, -1, (void *)sockfd);
A_PRINTF("ret = %d\n", ret);
return ret;
}
int releaseFile(PMSGPACK msg)
{
int ret = -1;
PUSER_INFO usr = findUserByAddress(&msg->address);
if(usr != NULL)
{
if((msg->addon) && (msg->addon->data))
{
unsigned long packageNo = atoi(msg->addon->data);
PFILEINFO file = getFileInfo(usr, packageNo, 0);
if(file)
{
PFILEINFO fileNod;
LOCK_SENDFILE(
fileNod = sendFileList;
while(fileNod)
{
PFILEINFO tmp = fileNod;
fileNod = fileNod->next;
if((tmp->usr == file->usr) && (tmp->packageNo == file->packageNo))
{
del_node((void**)&sendFileList, tmp);
delFileEx(tmp);
ret = 0;
}
}
);
}
}
}
return ret;
}
static void *fileTransfer(void *arg)
{
PCLIENTINFO cliInfo = (PCLIENTINFO)arg;
unsigned char recvBuf[2048];
PUSER_INFO usr;
int size;
PMSGPACK msg = NULL;
PRINTF("comes a client!\n");
do {
REQFILEINFO fileInfo;
PFILEINFO file;
// check wether the user is valid
usr = findUserByAddress(&cliInfo->address);
if(usr == NULL)
break;
PRINTF("usr:[%s]\n", usr->name);
// check if there is some file waiting to be send
if(getFileNumberOfUsr(usr) <= 0)
break;
// recv GETFILEDATA cmd
size = read(cliInfo->connfd, recvBuf, sizeof(recvBuf));
if(size <= 0)
break;
PRINTF("recv content = [%s]\n", recvBuf);
msg = (PMSGPACK)malloc(sizeof(MSGPACK));
parseRawMsg(recvBuf, size, msg);
if(parseRawRequestFileMsg(msg->addon->data, &fileInfo) < 0)
break;
// check if have the file to be send
file = getFileInfo(usr, fileInfo.packageNo, fileInfo.fileNo);
if(file == NULL)
break;
switch(GET_MODE(msg->cmd))
{
case IPMSG_GETFILEDATA:
PRINTF("[IPMSG_GETFILEDATA]\n");
if(file->flags != IPMSG_FILE_REGULAR)
break;
uploadFile(cliInfo->connfd, file);
break;
case IPMSG_GETDIRFILES:
PRINTF("[IPMSG_GETDIRFILES]\n");
if(file->flags != IPMSG_FILE_DIR)
break;
uploadFolder(cliInfo->connfd, file);
break;
}
} while(0);
if(msg)
delMsgEx(msg);
close(cliInfo->connfd);
free(cliInfo);
return NULL;
}
static void *fileServer(void *arg)
{
int tcpSock = getTcpSock();
while(1)
{
PCLIENTINFO cliInfo = malloc(sizeof(CLIENTINFO));
socklen_t cliAddrLen = sizeof(cliInfo->address);
pthread_t transfer;
if((cliInfo->connfd = accept(tcpSock, (struct sockaddr*)&cliInfo->address, &cliAddrLen)) < 0)
printf("\nUnknown error!!\n");
else
pthread_create(&transfer, NULL, &fileTransfer, (void*)cliInfo);
}
return NULL;
}
static int packFile(PMSG_ADDON addon, PFILEINFO file)
{
char tmpBuf[1024];
// 文件序号:文件名:大小:修改时间:文件属性
sprintf(tmpBuf, "\a%x:%s:%x:%x:%x:", file->FileNo, file->name, file->size, file->mtime, file->flags);
if(addon->data)
{
addon->data = realloc(addon->data, addon->len + strlen(tmpBuf));
strcpy(&addon->data[addon->len - 1], tmpBuf);
addon->len += strlen(tmpBuf);
}
else
{
addon->len = strlen(tmpBuf) + 1;
addon->data = malloc(
飞鸽传书源码,linux,windowsC语言程序,



《飞鸽传书:跨平台C语言实现的通信利器》 飞鸽传书,作为一款经典的数据传输软件,因其简洁的界面和高效的数据传输能力,深受用户喜爱。本项目是其源码版本,专为对底层通信机制感兴趣的开发者提供,采用C语言编写,实现了在Windows和Linux操作系统上的跨平台运行,这在程序设计领域具有相当的技术挑战性。 C语言,作为一种基础且强大的编程语言,以其高效、灵活和可移植性强的特点,被广泛用于系统级编程和嵌入式开发。在这个项目中,C语言被用来构建飞鸽传书的核心功能,包括数据包封装、网络通信、多线程处理以及文件传输等。开发者可以深入研究源码,理解如何利用C语言来处理复杂的网络通信问题,提升自身的编程技能。 在Linux环境下运行的软件通常需要对操作系统的API有深入理解。在这个项目中,开发者使用了POSIX标准的API,如socket接口进行网络编程,pthreads库实现多线程,并可能涉及文件系统操作和进程间通信(IPC)。通过分析源码,学习者可以了解到如何在Linux下编写跨进程通信的程序,理解系统调用的工作原理。 在Windows平台上,C语言同样可以调用Win32 API来实现类似的功能。在飞鸽传书的Windows版本中,可能涉及到Windows套接字(Winsock)库进行网络通信,Windows线程和进程API处理并发,以及文件I/O操作。这对于想要深入理解Windows系统编程的开发者来说,是一份宝贵的参考资料。 my_ipmsg这个文件很可能是项目的主程序或核心模块,它可能包含了飞鸽传书的核心逻辑,如用户身份验证、消息广播、文件传输等关键功能。通过阅读和调试这个文件,我们可以了解整个通信协议的实现细节,包括数据包的结构、加密解密方法、错误处理策略等。 这个飞鸽传书的源码项目为学习和研究跨平台C语言编程、网络通信和多线程技术提供了宝贵的机会。无论是初学者还是经验丰富的开发者,都能从中获益,深化对底层系统和网络编程的理解,提升自身的技术水平。同时,这也是一个很好的实践项目,可以帮助开发者将理论知识应用到实际的软件开发中,实现从理论到实践的飞跃。





































- 1

- #完美解决问题
- #运行顺畅
- #内容详尽
- #全网独家
- #注释完整
- yy12144791912012-12-16这个资源还行,挺有技术含量。
- Jade_jieyuanl2018-04-05很好的资源,值得鉴借。
- 卓桐2013-07-01不知到linux里面怎么用,终端也没提示

- 粉丝: 1
- 资源: 10
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- ,,西门子SMART200程序 PID的控制写法,突破8路,PID直接做成子程序,无密码,直接调用 ,西门子SMART200程序; PID控制写法; 突破8路; PID子程序; 无密码调用; 控制
- 企业数据治理方案:数据仓库统一数据分析系统建设方案.ppt
- 数字化it平台架构与应用蓝图建设方案 (1).ppt
- 数字化it平台架构与应用蓝图建设方案.ppt
- 智能工厂生产制造执行系统(MES)建设方案.ppt
- YOLOv12测试训练集
- 自考03709马克思主义
- ,,Modbus RTU 51单片机从机工程源码与昆仑通泰触摸屏测试工程文件 支持485和232串口通信,该从机源码支持51系列和STC12系列单片机,支持功能码01,02,03,04,05,06
- 2001-2023年上市公司数字化转型词频统计数据(年报词频统计、MD&A报告词频统计衡量两种方式)(吴非、赵宸宇、甄红线300+关键词三种方法).rar
- ,,C#联合halcon开发的通用视觉框架,可供初学者使用,是一C#联合halcon开发的通用视觉框架,可供初学者使用,是一 个不错的学习框架,发的是源码,发完不 ,发的是源码源码 ,C#联合Halc
- 基于人工智能的投资系统概念验证项目 项目目标是探索如何使用 AI 来辅助投资决策 本项目仅用于教育目的,不适用于实际交易或投资
- ,,基于DELM深度极限学习机的回归预测MATLAB代码 代码注释清楚 main为主程序,可以读取EXCEL数据,使用自己数据集 很方便,初学者容易上手 ,核心关键词:DELM深度极限学习
- 全国POI兴趣点数据2024年
- ,,Matlab学习卡尔曼滤波以及状态观测器的各种实例代码和模型 讲解,各种卡尔曼滤波的m代码,可以一行一行讲(KF,EKF,UKF,SRUKF,CKF,SRCKF等) KF,EKF,UKF,SRUK
- 一彩进销存管理软件2025正式版/功能不限制/可长期用
- ,,欧姆龙程序,Sysmac Studio伺服程序打包块,直接调用,并实现以下功能: 硬件:NJ101-1000 R88D-KN01H系列伺服 输入信号如下: 1:使能输入和故障复位 2:点动正


