【使用C++在Linux下通过socket实现TCP客户端和服务端进行文件收发】

以下是一个使用C++在Linux下通过socket实现TCP客户端和服务端进行文件收发的示例代码:

客户端代码:

#include <iostream>
#include <fstream>
#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#define BUFFER_SIZE 1024

void sendFile(int socketFd, const std::string& filename) {
    std::ifstream file(filename, std::ios::binary);
    if (!file) {
        std::cerr << "Failed to open file: " << filename << std::endl;
        return;
    }

    char buffer[BUFFER_SIZE];
    while (!file.eof()) {
        file.read(buffer, BUFFER_SIZE);
        ssize_t bytesRead = file.gcount();
        ssize_t bytesSent = send(socketFd, buffer, bytesRead, 0);
        if (bytesSent != bytesRead) {
            std::cerr << "Failed to send file" << std::endl;
            break;
        }
    }

    file.close();

    // 发送文件结束标志
    char fileEndFlag = '\0';
    send(socketFd, &fileEndFlag, sizeof(char), 0);
}

int main() {
    std::string serverIp = "127.0.0.1";
    int serverPort = 8888;
    std::string filename = "test.txt";

    int socketFd = socket(AF_INET, SOCK_STREAM, 0);
    if (socketFd == -1) {
        std::cerr << "Failed to create socket" << std::endl;
        return 1;
    }

    struct sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(serverPort);
    if (inet_pton(AF_INET, serverIp.c_str(), &(serverAddr.sin_addr)) <= 0) {
        std::cerr << "Invalid server IP address" << std::endl;
        return 1;
    }

    if (connect(socketFd, reinterpret_cast<struct sockaddr*>(&serverAddr), sizeof(serverAddr)) == -1) {
        std::cerr << "Failed to connect to the server" << std::endl;
        return 1;
    }

    sendFile(socketFd, filename);

    close(socketFd);

    return 0;
}

服务端代码:

#include <iostream>
#include <fstream>
#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

#define BUFFER_SIZE 1024

void receiveFile(int clientSocket, const std::string& filename) {
    std::ofstream file(filename, std::ios::binary);
    if (!file) {
        std::cerr << "Failed to create file: " << filename << std::endl;
        return;
    }

    char buffer[BUFFER_SIZE];
    while (true) {
        ssize_t bytesRead = recv(clientSocket, buffer, BUFFER_SIZE, 0);
        if (bytesRead <= 0) {
            break;
        }
        file.write(buffer, bytesRead);
    }

    file.close();
}

int main() {
    int serverPort = 8888;
    std::string filename = "received.txt";

    int listenSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (listenSocket == -1) {
        std::cerr << "Failed to create socket" << std::endl;
        return 1;
    }

    struct sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(serverPort);
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(listenSocket, reinterpret_cast<struct sockaddr*>(&serverAddr), sizeof(serverAddr)) == -1) {
        std::cerr << "Failed to bind socket" << std::endl;
        return 1;
    }

    if (listen(listenSocket, 5) == -1) {
        std::cerr << "Failed to listen on socket" << std::endl;
        return 1;
    }

    while (true) {
        struct sockaddr_in clientAddr{};
        socklen_t clientAddrLen = sizeof(clientAddr);

        int clientSocket = accept(listenSocket, reinterpret_cast<struct sockaddr*>(&clientAddr), &clientAddrLen);
        if (clientSocket == -1) {
            std::cerr << "Failed to accept client connection" << std::endl;
            continue;
        }

        receiveFile(clientSocket, filename);

        close(clientSocket);
    }

    close(listenSocket);

    return 0;
}

这两个程序使用了多线程来实现并发处理多个客户端的连接和文件收发。在服务端代码中,每当有新的客户端连接时,会创建一个新的线程来处理该客户端的请求。在客户端代码中,通过socket连接到服务端,并使用send函数发送文件内容到服务端。

请确保将代码中的文件名、IP地址和端口号等参数设置为正确的值。运行服务端程序后,可以通过运行多个客户端程序来测试并发连接和文件收发的功能。

  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
【资源说明】 1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载食用体验! 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 【项目介绍】 基于Qt和C++开发的网盘系统源码(含客户端+服务端)+项目说明+详细注释.zip 项目描述:采用C/S架构,数据库存储用户信息,磁盘存储用户文件。通过网盘,用户可以搜索好友,加好友,与好友聊天。同时可以上传下载、编辑文件,以及与好友分享文件。 1.使用C++面向对象编程特性。 2.通过信号和槽机制将对象发送的信号和接收者的槽函数关联起来,信号产生时,与之关联的槽函数就被执行。 3.使用SQLite3数据库存储用户信息和好友关系。 4.数据库和用户界面的操作类定义成单例模式,避免操作类频繁地创建消费。 5.客户端服务端通过TCP Socket网络编程进行收发协议数据单元(PDU)。 6.客户端上传文件以字节流传输,使用定时器(Qtimer型指针)避免文件出现粘包(文件内容与请求)情况。
### 回答1: 这是一段 Linux使用 C 语言实现 socket 编程的示例代码(客户端): ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8888 #define MAXDATASIZE 100 int main(int argc, char *argv[]) { int sockfd, num; char buf[MAXDATASIZE]; struct sockaddr_in server; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket() error."); exit(1); } server.sin_family = AF_INET; server.sin_port = htons(PORT); server.sin_addr.s_addr = inet_addr("127.0.0.1"); bzero(&(server.sin_zero), 8); if (connect(sockfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) { perror("connect() error."); exit(1); } if ((num = recv(sockfd, buf, MAXDATASIZE, 0)) == -1) { perror("recv() error."); exit(1); } buf[num - 1] = '\0'; printf("Server Message: %s\n", buf); close(sockfd); return 0; } ``` 这是一段 Linux使用 C 语言实现 socket 编程的示例代码(服务器端): ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 8888 #define BACKLOG 1 int main() { int sockfd, new_fd; struct sockaddr_in server; struct sockaddr_in client; int sin_size; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket() error."); exit(1); } int opt = SO_REUSEADDR; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); server.sin_family = AF_INET; server.sin_port = htons(PORT); server.sin_addr ### 回答2: 下面是一个使用C语言编写的在Linux使用Socket编程实现客户端服务端对话的示例代码: 服务端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #define MAX_BUFFER_SIZE 1024 int main() { int server_socket, client_socket; struct sockaddr_in server_address, client_address; char buffer[MAX_BUFFER_SIZE]; int str_len; socklen_t client_address_size; server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket == -1) { perror("socket() error"); exit(1); } memset(&server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_port = htons(1234); server_address.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == -1) { perror("bind() error"); exit(1); } if (listen(server_socket, 5) == -1) { perror("listen() error"); exit(1); } client_address_size = sizeof(client_address); client_socket = accept(server_socket, (struct sockaddr*)&client_address, &client_address_size); if (client_socket == -1) { perror("accept() error"); exit(1); } while (1) { str_len = read(client_socket, buffer, MAX_BUFFER_SIZE - 1); if (str_len == -1) { perror("read() error"); exit(1); } buffer[str_len] = '\0'; printf("Client: %s\n", buffer); printf("Server: "); fgets(buffer, MAX_BUFFER_SIZE, stdin); if (!strcmp(buffer, "q\n") || !strcmp(buffer, "Q\n")) { break; } write(client_socket, buffer, strlen(buffer)); } close(client_socket); close(server_socket); return 0; } ``` 客户端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #define MAX_BUFFER_SIZE 1024 int main() { int client_socket; struct sockaddr_in server_address; char buffer[MAX_BUFFER_SIZE]; int str_len; client_socket = socket(AF_INET, SOCK_STREAM, 0); if (client_socket == -1) { perror("socket() error"); exit(1); } memset(&server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_port = htons(1234); server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); if (connect(client_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == -1) { perror("connect() error"); exit(1); } while (1) { printf("Client: "); fgets(buffer, MAX_BUFFER_SIZE, stdin); if (!strcmp(buffer, "q\n") || !strcmp(buffer, "Q\n")) { break; } write(client_socket, buffer, strlen(buffer)); str_len = read(client_socket, buffer, MAX_BUFFER_SIZE - 1); if (str_len == -1) { perror("read() error"); exit(1); } buffer[str_len] = '\0'; printf("Server: %s\n", buffer); } close(client_socket); return 0; } ``` 以上是一个简单的客户端服务端对话的例子,运行服务端程序后,再运行客户端程序就可以实现在终端上进行对话。客户端输入的内容会发送给服务端,在服务端的终端显示,并等待服务端的回复,服务端在接收到客户端的消息后会回复给客户端,并在客户端的终端显示。当输入"q"或"Q"时,客户端服务端会断开连接并退出程序。 ### 回答3: 下面是一段使用C语言在Linux实现客户端服务端对话的代码: 客户端代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #define BUF_SIZE 1024 int main() { int client_socket; struct sockaddr_in server_address; char buffer[BUF_SIZE]; // 创建套接字 client_socket = socket(AF_INET, SOCK_STREAM, 0); if (client_socket == -1) { perror("创建套接字失败"); exit(1); } // 设置服务器地址 memset(&server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器IP地址 server_address.sin_port = htons(8888); // 服务器端口号 // 连接服务器 if (connect(client_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == -1) { perror("连接服务器失败"); exit(1); } while (1) { // 输入要发送的消息 printf("请输入要发送的消息(输入exit退出):"); fgets(buffer, BUF_SIZE, stdin); // 发送消息给服务器 if (send(client_socket, buffer, strlen(buffer), 0) == -1) { perror("发送消息给服务器失败"); exit(1); } // 退出循环的条件 if (strcmp(buffer, "exit\n") == 0) { break; } // 接收服务器返回的消息 memset(buffer, 0, BUF_SIZE); if (recv(client_socket, buffer, BUF_SIZE - 1, 0) == -1) { perror("接收服务器消息失败"); exit(1); } // 打印服务器返回的消息 printf("服务器消息:%s", buffer); } // 关闭套接字 close(client_socket); return 0; } ``` 服务端代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #define BUF_SIZE 1024 int main() { int server_socket, client_socket; struct sockaddr_in server_address, client_address; socklen_t client_address_size; char buffer[BUF_SIZE]; // 创建套接字 server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket == -1) { perror("创建套接字失败"); exit(1); } // 设置服务器地址 memset(&server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); // 任意IP地址 server_address.sin_port = htons(8888); // 服务器监听端口号 // 绑定套接字 if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == -1) { perror("绑定套接字失败"); exit(1); } // 监听套接字 if (listen(server_socket, 5) == -1) { perror("监听套接字失败"); exit(1); } printf("等待客户端连接...\n"); // 接受客户端连接 client_address_size = sizeof(client_address); client_socket = accept(server_socket, (struct sockaddr*)&client_address, &client_address_size); if (client_socket == -1) { perror("接受客户端连接失败"); exit(1); } printf("客户端连接成功\n"); while (1) { // 接收客户端发送的消息 memset(buffer, 0, BUF_SIZE); if (recv(client_socket, buffer, BUF_SIZE - 1, 0) == -1) { perror("接收客户端消息失败"); exit(1); } // 退出循环的条件 if (strcmp(buffer, "exit\n") == 0) { break; } // 打印客户端发送的消息 printf("客户端消息:%s", buffer); // 回复客户端消息 if (send(client_socket, buffer, strlen(buffer), 0) == -1) { perror("回复客户端消息失败"); exit(1); } } // 关闭套接字 close(client_socket); close(server_socket); return 0; } ``` 这段代码实现了一个简单的客户端服务端对话的功能。客户端使用`socket`函数创建了一个套接字,然后通过`connect`函数连接到服务器上。连接成功后,进入一个循环,循环中首先通过`fgets`函数输入要发送的消息,然后通过`send`函数将消息发送给服务器。接着接收服务器返回的消息,再打印出来。如果输入的消息是"exit",则退出循环,关闭套接字,程序结束。 服务端使用`socket`函数创建一个套接字,并设置服务器地址。然后通过`bind`函数将套接字与服务器地址绑定,并通过`listen`函数监听套接字。接着使用`accept`函数接受客户端连接,接收成功后进入一个循环。循环中首先接收客户端发送的消息,然后通过`send`函数将消息回复给客户端。如果接收到的消息是"exit",则退出循环,关闭套接字,程序结束。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西乡塘打工人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值