Linux多线程五 tcp传输文件

server

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>

#define FILE_NAME_MAX_SIZE 512 
char buf[1024];//缓冲区
int ad[10];//最大连接数
const int port = 8085;
const char* ip="172.16.10.207";

void *thread_fun1(void *arg)
{
    //while(1)
     //    {
    //         memset(buf, '\0', sizeof(buf));//清空buf
    //         ssize_t _s=read(ad[(int)arg],buf,sizeof(buf)-1);
    //         if(_s>0)
    //         {
    //            buf[_s]=0;
    //            printf("client# %s\n",buf);   
    //         }
    //         else
    //         {
    //            printf("client is quit!\n");
    //            break;
    //         }
    //         write(ad[(int)arg],buf,strlen(buf));
    //     }
    // return NULL;
    while(1)
    {

    
        if (recv(ad[(int)arg], buf, 1024, 0) < 0)
		{
			printf("Server Recieve Data Failed:");
			break;
		}

		// 然后从buffer(缓冲区)拷贝到file_name中 
		char file_name[FILE_NAME_MAX_SIZE + 1];
		bzero(file_name, FILE_NAME_MAX_SIZE + 1);
		strncpy(file_name, buf, strlen(buf)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buf));
		printf("%s\n", file_name);
		// 打开文件并读取文件数据 
		FILE *fp = fopen(file_name, "r");
		if (NULL == fp)
		{
			printf("File:%s Not Found\n", file_name);
		}
		else
		{

			bzero(buf,1024);
			int length = 0;
			// 每读取一段数据,便将其发送给客户端,循环直到文件读完为止 
			while ((length = fread(buf, sizeof(char), 1024, fp)) > 0)
			{
				if (send(ad[(int)arg], buf, length, 0) < 0)
				{
					printf("Send File:%s Failed./n", file_name);
					break;
				}
				bzero(buf, 1024);
			}
			// 关闭文件 
			fclose(fp);
			printf("File:%s Transfer Successful!\n", file_name);
		}
		// 关闭与客户端的连接 
		close(ad[(int)arg]);
    }   
}

// void *thread_fun2(void *arg)
// {
//     while(1)
//         {
//             memset(buf, '\0', sizeof(buf));//清空buf
//             ssize_t _s=write(ad[(int)arg],buf,strlen(buf));
//             if(_s>0)
//             {
//                buf[_s]=0;
//                printf("client# %s\n",buf);   
//             }
//             else
//             {
//                printf("client is quit!\n");
//                break;
//             }
//         }
//     return NULL;
// }

int main(int argc,char* argv[])
{
    

    int sock=socket(AF_INET,SOCK_STREAM,0);//打开一个网络通信窗口
    if(sock<0)
    {
        perror("socket");
        exit(1);
    }

    struct sockaddr_in local;//服务端
    local.sin_family=AF_INET;   //地址族
    local.sin_port=htons(port);//16位TCP/UDP端口号
    //local.sin_addr.s_addr=inet_addr(ip);//32位IP地址
    local.sin_addr.s_addr=htonl(INADDR_ANY);
    socklen_t len=sizeof(local);

   if(bind(sock,(struct sockaddr*)&local,len)<0)//绑定一个固定的网络地址和端口号
   {
     perror("bind");
     exit(2);
    }

    if(listen(sock,5)<0)//导致套接口从closed状态换到listen状态
    {
        perror("listen");
        exit(3);
    }

    pthread_t tid[10];
    int err;
    int i=0;
    //socklen_t len=sizeof(struct sockaddr_in);

    while(1)
    {
        struct sockaddr_in remote;//用于客户端的socket定义和赋值
        socklen_t remote_len = sizeof(remote);
        ad[i]=accept(sock,(struct sockaddr*)&remote,&remote_len);
        if(ad[i]<0)
        {
            perror("accept");
            continue;
        }
        printf("client,ip:%s,port:%d\n",inet_ntoa(remote.sin_addr)\
               ,ntohs(remote.sin_port));
        err=pthread_create(&tid[i],NULL,thread_fun1,(void *)i);
        //err=pthread_create(&tid[i],NULL,thread_fun2,(void *)i);
        if(err !=0)
        {
            printf("create new thread failed\n");
            close(ad[i]);
        }
        i++;
    }  
    close(sock);  
    return 0;
}

client


#include<netinet/in.h>  // sockaddr_in 
#include<sys/types.h>  // socket 
#include<sys/socket.h>  // socket 
#include<stdio.h>    // printf 
#include<stdlib.h>    // exit 
#include<string.h>    // bzero 

#define SERVER_PORT 8085
#define BUFFER_SIZE 1024 
#define FILE_NAME_MAX_SIZE 512 

int main()
{
	// 声明并初始化一个客户端的socket地址结构 
	struct sockaddr_in client_addr;
	//设置client_addr前size个字节为0
	bzero(&client_addr, sizeof(client_addr));
	client_addr.sin_family = AF_INET;
	client_addr.sin_addr.s_addr = htons(INADDR_ANY);
	client_addr.sin_port = htons(0);
	// 创建socket,若成功,返回socket描述符 
	int client_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (client_socket_fd < 0)
	{
		perror("Create Socket Failed:");
		exit(1);
	}
	// 绑定客户端的socket和客户端的socket地址结构 非必需 
	if (-1 == (bind(client_socket_fd, (struct sockaddr*)&client_addr, sizeof(client_addr))))
	{
		perror("Client Bind Failed:");
		exit(1);
	}
	// 声明一个服务器端的socket地址结构,并用服务器那边的IP地址及端口对其进行初始化,用于后面的连接 
	struct sockaddr_in server_addr;
	bzero(&server_addr, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	//将IP地址从字符串格式转换成网络地址格式
	if (inet_pton(AF_INET, "172.16.10.207", &server_addr.sin_addr) == 0)
	{
		perror("Server IP Address Error:");
		exit(1);
	}
	server_addr.sin_port = htons(SERVER_PORT);//将主机字节顺序转换为网络字节顺序
	//和int有点像用来表示长度
	socklen_t server_addr_length = sizeof(server_addr);
	// 向服务器发起连接,连接成功后client_socket_fd代表了客户端和服务器的一个socket连接 
	if (connect(client_socket_fd, (struct sockaddr*)&server_addr, server_addr_length) < 0)
	{
		perror("Can Not Connect To Server IP:");
		exit(0);
	}

	// 输入文件名 并放到缓冲区buffer中等待发送 
	char file_name[FILE_NAME_MAX_SIZE + 1];
	char file_name_save[FILE_NAME_MAX_SIZE + 1];
	bzero(file_name, FILE_NAME_MAX_SIZE + 1);
	printf("Please Input File Name On Server:\t");
	// scanf()函数返回成功赋值的数据项数,读到文件末尾出错时则返回EOF
	scanf("%s", file_name);
	char buffer[BUFFER_SIZE];
	bzero(buffer, BUFFER_SIZE);
	//把file_name所指由NULL结束的字符串的前n个字节复制到buffer所指的数组中。
	strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
	// 向client_socket_fd发送buffer中的数据 
	if (send(client_socket_fd, buffer, BUFFER_SIZE, 0) < 0)
	{
		perror("Send File Name Failed:");
		exit(1);
	}

	//输入要保存的地址
	printf("Please Input File Name to Save:\t");
	scanf("%s", file_name_save);
	// 打开文件,准备写入 
	FILE *fp = fopen(file_name_save, "w");
	if (NULL == fp)
	{
		printf("File:\t%s Can Not Open To Write\n", file_name_save);
		exit(1);
	}

	// 从服务器接收数据到buffer中 
	// 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止 
	bzero(buffer, BUFFER_SIZE);
	int length = 0;
	//不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据
	//用buffer来存放recv函数接收到的数据
	while ((length = recv(client_socket_fd, buffer, BUFFER_SIZE, 0)) > 0)
	{
		//buffer所指的内容输出到fp这个文件中,
		if (fwrite(buffer, sizeof(char), length, fp) < length)
		{
			printf("File:\t%s Write Failed\n", file_name);
			break;
		}
		bzero(buffer, BUFFER_SIZE);
	}
	// 接收成功后,关闭文件,关闭socket 
	printf("Receive File:\t%s From Server IP Successful!\n", file_name);
	close(fp);
	close(client_socket_fd);
	return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值