客户端(服务器下载文件)

一、客户端代码

客户端代码

cs 复制代码
//实现TCP客户端通信
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>

int main(int argc, const char *argv[])
{
	
	//1、创建套接字
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0)
	{
		printf("创建失败\n");
		return -1;
	}
	/*
	//2、绑定套接字
	//填写自己的地址信息,不是必要的
	struct sockaddr_in clientaddr;
	clientaddr.sin_family=AF_INET;
	clientaddr.sin_port=htons(10000);
	clientaddr.sin_addr.s_addr=inet_addr("192.168.124.29");
	int bind_ret=bind(sockfd,(struct sockaddr *)&clientaddr,sizeof(clientaddr));
	if(bind_ret<0)
	{
		printf("绑定失败\n");
		return -1;
	}*/
	//3、建立连接connect
	//填写对方信息
	struct sockaddr_in destaddr;
	destaddr.sin_family=AF_INET;
	destaddr.sin_port=htons(8888);
	destaddr.sin_addr.s_addr=inet_addr("192.168.124.29");
	int connect_ret=connect(sockfd,(struct sockaddr*)&destaddr,sizeof(destaddr));
	if(connect_ret<0)
	{
		printf("连接失败\n");
		return -1;
	}
	//4、发送数据send
	while(1)
	{
		char buf[100];
		scanf("%s",buf);
		send(sockfd,buf,100,0);
		int fd=open(buf,O_WRONLY|O_CREAT|O_TRUNC,0664);
		if(fd<0)
		{
			printf("open failed");
			return -1;
		}
		while(1)
		{
			bzero(buf,100);
			int ret=recv(sockfd,buf,100,0);
			printf("%s",buf);
			if(ret==0)
				break;
			write(fd,buf,ret);
		}
		
	}
	//6、关闭文件
	close(sockfd);
	
	return 0;
}

二、服务器代码

服务器使用IO多路复用

cs 复制代码
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include<fcntl.h>

#define SERVERADDR "192.168.124.29"
#define PORT 8888

int main(int argc, const char *argv[]) {
    // 创建套接字
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd < 0) {
        perror("socket failed");
        return -1;
    }

    // 绑定套接字
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(PORT);
    serveraddr.sin_addr.s_addr = inet_addr(SERVERADDR);
    if (bind(listenfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0) {
        perror("bind failed");
        return -1;
    }

    // 监听套接字
    if (listen(listenfd, 20) < 0) {
        perror("listen failed");
        return -1;
    }
	//定义文件描述符表
    fd_set master_fds, read_fds;
    int max_fd = listenfd;
	//清空文件描述符表
    FD_ZERO(&master_fds);
	//将监听套接字加入文件描述符表
    FD_SET(listenfd, &master_fds);

    while (1)
	{
        read_fds = master_fds;

        // 监视文件描述符集,进程通知内核监视的内核是否准备就绪(是否有IO事件)
        int activity = select(max_fd + 1, &read_fds, NULL, NULL, NULL);
        if (activity < 0) 
		{
            perror("select failed");
            return -1;
        }

        // 处理新连接
        if (FD_ISSET(listenfd, &read_fds))
		{
            struct sockaddr_in clientaddr;
            socklen_t len = sizeof(clientaddr);
            int client_fd = accept(listenfd, (struct sockaddr*)&clientaddr, &len);
            if (client_fd < 0)
			{
                perror("accept failed");
                continue;
            }
            printf("New connection from %s:%hu\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
            //将新创建的客户端文件描述符加入到文件描述符表当中
			FD_SET(client_fd, &master_fds);
            if (client_fd > max_fd)
			{
                max_fd = client_fd;
            }
        }

        // 处理已连接客户端的数据
        for (int i = listenfd + 1; i <= max_fd; ++i)
		{
            if (FD_ISSET(i, &read_fds))
			{
                char buf[100];
                bzero(buf, 100);
                int ret = read(i, buf, 100);
				int fd=open(buf,O_RDONLY);
				if(fd<0)
				{
					printf("open failed\n");
					return -1;
				}
				char file[100];
				while(1)
				{
					bzero(file,100);
				   int read_ret = read(fd,file,100);
				   printf("%d ",read_ret);
				   if(read_ret==0)
					   break;
                  send(i, file, read_ret,0);
				}
				printf("download ok\n");
            }
        }
    }

    close(listenfd);
    return 0;
}
相关推荐
梦游钓鱼1 小时前
在window终端创建docker容器的问题
运维·docker·容器
孤寂大仙v1 小时前
【Linux笔记】理解文件系统(上)
linux·运维·笔记
沉默的八哥2 小时前
K8S高可用Web应用部署方案
运维
winyh52 小时前
Vite 打包后Nginx部署配置
运维·nginx
pyliumy3 小时前
在基于Arm架构的华为鲲鹏服务器上,针对openEuler 20.03 LTS操作系统, 安装Ansible 和MySQL
服务器·架构·ansible
运维小贺3 小时前
Nginx常用的模块
运维·nginx·正则表达式
努力学习的小廉3 小时前
深入了解Linux —— 调试程序
linux·运维·服务器
努力学习的小廉3 小时前
深入了解Linux —— git三板斧
linux·运维·git
只做开心事4 小时前
Linux网络之数据链路层协议
linux·服务器·网络