socket编程(四)

client端向server端发送文件。

在server中,创建一个子进程接收文件。

server:

#include <cstdlib>
#include <fstream>
#include <iomanip>   
#include <iostream>  

#include <string.h>
#include <errno.h> 
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/wait.h>
#include <netinet/in.h>
#include <netdb.h>


using namespace std;

// the file receive function
// this will handle connection for each client
int recv_handler(void *socket_desc)
{
        // get the socket descriptor
        int client_sock = *(int *)socket_desc;
        unsigned long read_size;
        char file_name[50], file_buf[1024];
        int fd;

        // receive file pathname
        if (recv(client_sock, file_name, sizeof(file_name), 0) == -1) {
                perror("recv failed");
                return 1;
        }

        if ((fd = open(file_name, O_RDWR | O_TRUNC | O_CREAT, 0664)) == -1) {
                perror("open");
                return 1;
        }

        // receive file
        while((read_size = recv(client_sock, file_buf, sizeof(file_buf), 0)) > 0) {
                if (write(fd, file_buf, read_size) == -1) {
                        perror("write");
                        close(fd);
                        return 1;
                }
        }
        if (read_size == 0) {
                cout << "client disconnected" << endl;
                fflush(stdout);
        } else if (read_size == -1) {
                cout << "recv failed" << endl;
        }

        close(fd);
        return 0;
}


int main(int argc, char *argv[])
{
        int socket_desc, client_sock, c;
        struct sockaddr_in server, client;
        pid_t fpid;

        // create a socket
        socket_desc = socket(AF_INET, SOCK_STREAM, 0);
        if (socket_desc == -1)
                perror("couldn't create socket");
        cout << "socket created" << endl;

        // prepare the sockaddr_in structure
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        server.sin_port = htons(8888);

        // enable address reuse
        int on = 1;
        if (setsockopt(socket_desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
                perror("setsockopt failed");
                return 1;
        }

        // bind
        if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {
                perror("bind failed");
                return 1;
        }
        cout << "bind done" << endl;

        // listen
        listen(socket_desc, 3);

        // accept incoming connection ...
        cout << "Waitting for incoming connections ..." << endl;
        c = sizeof(struct sockaddr_in);
        while ((client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *)&c))) {
                cout << "connection accepted" << endl;
                
                // receive file in chilaren process
                fpid = fork();
                if (fpid == 0) {
                        if (recv_handler(&client_sock) == 1) {
                                cout << "recv_handler() failed" << endl;
                                return 1;
                        }
                        return 0;
                } else if (fpid < 0) {
                        perror("fork()");
                        return 1;
                }
        }

        if (client_sock < 0) {
                perror("accept failed");
                return 1;
        }
        
        return 0;
}

client:

#include <cstdlib>
#include <fstream>
#include <iomanip>   
#include <iostream>  

#include <string.h>
#include <errno.h> 
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/wait.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h> //inet_addr
#include <sys/stat.h>
#include <stdlib.h> 
#include <stdio.h> 


using namespace std;

// 得到文件大小
unsigned long get_file_size(const char *file_name)
{
        struct stat buf;

        if (file_name == NULL) {
                cout << "file_name is null" << endl;
                return -1;
        }

        if (stat(file_name, &buf) == -1) {
                perror("get_file_size");
                return 0;
        }

        return (unsigned long)buf.st_size; 
}


int main(int argc, char *argv[])
{
        int sock, fd;
        struct sockaddr_in server;
        char file_name[50], *file_buf = NULL;
        unsigned long file_size;

        // create socket
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock == -1)
                cout << "couldn't create socket" << endl;
        cout << "socket created" << endl;

        // prepare sockaddr_in server
        server.sin_addr.s_addr = inet_addr("127.0.0.1");
        server.sin_family = AF_INET;
        server.sin_port = htons(8888);

        // connect to remote server
        if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
                perror("connect failed");
                return 1;
        }
        cout << "Connected" << endl;

        // get file pathname
        cout << "Enter file pathname: " << endl;
        cin.getline(file_name, sizeof(file_name));

        // prepare the file buffer
        if ((file_size = get_file_size(file_name)) == 0) {
                cout << "get file size failed" << endl;
                return 1;
        }
        file_buf = new char[file_size];
        if (file_buf == NULL) {
                cout << "new failed" << endl;
                return 1;
        }

        if ((fd = open(file_name, O_RDONLY)) == -1) {
                perror("open");
                goto out2;
        }
        if (read(fd, file_buf, file_size) == -1) {
                perror("read");
                goto out2;
        }
        close(fd);

        // send file pathname
        if (send(sock, file_name, sizeof(file_name), 0) == -1) {
                cout << "send file pathname failed" << endl;
                goto out1;
        }

        // send file
        if (send(sock, file_buf, file_size, 0) == -1) {
                cout << "send file failed" << endl;
                goto out1;
        }
        

out1:
        close(sock);
out2:
        if (file_buf != NULL)
                delete []file_buf;

        return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值