技术点:
chdir:将工作目录切到当前。
fprintf:拼接字符串。
服务器端:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#pragma pack(1)
struct file_info
{
char name[300];
int size; //-1表示为文件夹,非负整数表示普通文件
};
#pragma pack()
struct file_info fi;
const char* file_path; //要发送文件的路径
void* srv_thr(void* arg);
void send_file(int sock_conn, const char* path);
int send_regfile(int sock_conn, const char* path);
int send_dir(int sock_conn, const char* path);
int main(int argc, char** argv)
{
if(argc != 2)
{
fprintf(stderr, "命令语法错误!\n");
return -1;
}
if(access(argv[1], R_OK) != 0)
{
fprintf(stderr, "%s不存在或不可读!\n", argv[1]);
return -1;
}
signal(SIGPIPE, SIG_IGN);
//获取要发送的文件的路径
file_path = argv[1];
//第一步:创建监听套接字
//sock_listen:套接字描述符,用来唯一地标识一个套接字
//socket函数的第一个参数表示地址家族
//AF_INET:使用Internet地址家族,即采用TCP/IP网络标准
//socket函数的第二个参数表示套接字类型,主要有三种类型:
//SOCK_STREAM 即流套接字,用于TCP协议通信
//SOCK_DGRAM 即数据报套接字,用于UDP协议通信
//SOCK_RAW 即原始套接字,用于网络底层通信
//socket函数的第三个参数表示使用的通信协议,0表示使用默认的协议
int sock_listen = socket(AF_INET, SOCK_STREAM, 0);
//设置端口复用
int opt_val = 1;
setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val));
//第二步:给套接字绑定一个地址
struct sockaddr_in myaddr;
myaddr.sin_family = AF_INET; //指定地址家族为Internet地址家族
myaddr.sin_addr.s_addr = INADDR_ANY; //指定IP地址为本机任意地址
myaddr.sin_port = htons(<