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;
}