⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sender部分说明.cpp

📁 多线程文件的传输实现 需要在linux shell 下操作
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h> 

//********* 主Socket,用于接受5个socket的连接 *********//
int l_socket;
struct sockaddr_in adr_s;

//********* 对应于的5个多线程连接并传输文件的Socket *********//
int a_socket[5];
pthread_t thread_id[5];

//********* 文件读到内存中存放的5个位置 *********//
char *fileBlocks[5];
long fileLens[5];

//********* 标准错误处理 *********//
void EOP(const char* errorCode) { printf("Sender Error: %s;\n",errorCode); exit(1); }

//********* 得到指定文件的长度 *********//
int GetFileLength(char *filename) {
	int fsize = 0,temp;
	char buf[512];
	FILE * file=fopen(filename,"r");	
	if (file==NULL) EOP("No Such File.");
	while( (temp=fread(buf,1,512,file))!=0 ) {
		if(temp==-1) EOP("fread file error.");
		fsize+=temp;
	}
	fclose(file);
	return fsize;
}

//********* 为每个文件快计算长度 *********//
void CalculateFileLens(long total) {
	long len=total/5;
	for(int i=0;i<4;i++) fileLens[i]=len;
	fileLens[4]=total-len*4;
}

//********* 把指定文件读到内存中 *********//
void FillFileBlocks(char *filename) {
	int temp,byteread;
	char *buf_p;
	FILE *file = fopen(filename,"r");
	if (file==NULL) EOP("No Such File.");
	for(int i=0;i<5;i++) {
		fileBlocks[i] = (char*)malloc(sizeof(char)*fileLens[i]+1);
		fileBlocks[i][sizeof(char)*fileLens[i]] = 0;
		if (fileBlocks[i]==NULL) EOP("malloc failed.");
		temp = fileLens[i];
		buf_p = fileBlocks[i];
		while( (byteread=fread(buf_p,1,temp,file))!=0) {
			if (temp==-1) EOP("fill block failed.");
			buf_p+=byteread;
			temp-=byteread;
		}		
	}
}

//********* 初始化socket连接 *********//
void InitListenSocket(char *IPaddress,int port) {
	l_socket=socket(PF_INET,SOCK_STREAM,0); 
	  if(l_socket<0) EOP("socket create failed..");
	
	memset(&adr_s,0,sizeof adr_s);
	adr_s.sin_family=AF_INET;
	adr_s.sin_port=htons(port);
	adr_s.sin_addr.s_addr=inet_addr(IPaddress);
	if (adr_s.sin_addr.s_addr==INADDR_NONE) EOP("wrong address..");
}		

//********* 有线程调用发送文件块 *********//
void SendBlock(int id) {
	int temp;
	char *buf_p = fileBlocks[id];
	int len=fileLens[id];

	write(a_socket[id],&fileLens[id],sizeof(long));
	write(a_socket[id],&id,sizeof(int));

	while( (temp=write(a_socket[id],buf_p,len))!=0 ) {
		if(temp==-1) EOP("one sendblock() error.");
		len -= temp;
		buf_p += temp;
	}
	printf("Thread %d, Send OK.. -- %ld bytes --\n",id,fileLens[id]);
	close(a_socket[id]);
}

//********* 监听接受方的连接 *********//
void Listen() {
    int tmp;
    tmp=bind(l_socket,(struct sockaddr*)&adr_s,sizeof adr_s);
    if(tmp<0) EOP("bind failed..");

    tmp=listen(l_socket,5);
    if(tmp<0) EOP("listen failed");	
	
    struct sockaddr_in adr_a;
    int len = sizeof adr_a;
    int id[5];
    int t_s;
    for(int i=0;i<5;i++) {
        a_socket[i]=accept(l_socket,(struct sockaddr*)&adr_a,(socklen_t*)&len);
	if (a_socket[i]<0)  EOP("one socket accepting failed.");
	id[i] = i;

	//******* 抛出多线程,创建多Socket ********//
        t_s=pthread_create(&thread_id[i],NULL,(void*(*)(void*))SendBlock,(void*)id[i]);
	if(t_s!=0) EOP("one thread creating failed.");
    }
    close(l_socket);
}

int main(void) {
	char fileName[128],IP[20];
	
	printf("Input the filename you want to send: ");
	scanf("%s",fileName);
 	
	int flen = GetFileLength ( fileName );	

	printf("Then your IP address: ");
	scanf("%s",IP);

	CalculateFileLens ( flen );
	FillFileBlocks ( fileName );
	InitListenSocket(IP,8083);
	
	printf("Now waiting for connection..\n");
	Listen();
	
	for(int i=0;i<5;i++) pthread_join(thread_id[i],NULL);
	
	printf("+--Server Sending Complete--+\n");
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -