Reprint please indicate the source: http://blog.csdn.net/jmppok/article/details/18360595
C + + Network programming will inevitably encounter the need to transfer large data, large files, and due to the limitations of the socket itself buffer, about one time can only send about 4K of data, so in the transmission of large data clients need to subcontract, in the destination of the package. In fact, some message/communication middleware has been encapsulated, which provides a direct delivery of large data/file interface, in addition, the use of shared directories, FTP,SSH and other system commands to achieve large files/data is also a good way. 1. Based on the socket for transmission
Based on the socket for transmission is the key to control, the need for their own row subcontracting and packaging.
The principle is very simple then, let's take a look at the code directly.
Code references from: http://blog.csdn.net/ljd_1986413/article/details/7940938
FILE_SERVER.C--Socket File Transfer server-side sample code
#include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <stdlib.h > #include <string.h> #define hello_world_server_port 6666 #define Length_of_listen_ QUEUE #define BUFFER_SIZE 1024 #define FILE_NAME_MAX_SIZE int m Ain (int argc, char **argv) {//Set socket ' s address information//set a socket addresses structure SERVER_ADDR, generation
Table server Internet address and port struct sockaddr_in server_addr;
Bzero (&server_addr, sizeof (SERVER_ADDR));
server_addr.sin_family = af_inet;
SERVER_ADDR.SIN_ADDR.S_ADDR = htons (Inaddr_any); Server_addr.sin_port = htons (hello_wOrld_server_port); Create a Stream socket//creates a stream protocol (TCP) socket for the Internet, an interface int server_so that represents the server to the client with Server_socket
Cket = socket (pf_inet, sock_stream, 0);
if (Server_socket < 0) {printf ("Create socket failed!\n");
Exit (1); The socket and socket address structures are bound to the IF (bind (server_socket, struct sockaddr*) &server_addr, sizeof (s
ERVER_ADDR)) {printf ("Server Bind Port:%d failed!\n", hello_world_server_port);
Exit (1);
}//Server_socket is used to monitor if (Listen (Server_socket, length_of_listen_queue)) {
printf ("Server Listen failed!\n");
Exit (1); }//Server side has been running to continuously provide services to clients while (1) {//define client socket address structure CLIENT_ADDR, when receiving After the request from the client, call Accept//Accept the request and write information such as the address and port of the client side to CLIENT_ADDR sTruct sockaddr_in client_addr;
socklen_t length = sizeof (CLIENT_ADDR);
Accept a connection request from the client side to the server and save the information in CLIENT_ADDR///If there is no connection request, wait until there is a connection request, which is the feature of the accept function and can be Use Select () to implement timeout detection//Accpet Returns a new socket that is used to communicate with the client connected to the server//New_serv here Er_socket represents this communication channel int new_server_socket = accept (server_socket, struct sockaddr*) &client_addr, &le
Ngth);
if (New_server_socket < 0) {printf ("Server Accept failed!\n");
Break
} Char Buffer[buffer_size];
bzero (buffer, sizeof (buffer));
Length = recv (new_server_socket, buffer, buffer_size, 0);
if (length < 0) {printf ("Server recieve Data failed!\n");
Break } Char File_name[file_name_max_size + 1];
Bzero (file_name, sizeof (file_name)); strncpy (file_name, buffer, strlen (buffer) > file_name_max_size?
File_name_max_size:strlen (buffer));
FILE *FP = fopen (file_name, "R");
if (fp = = NULL) {printf ("file:\t%s not found!\n", file_name);
else {bzero (buffer, buffer_size);
int file_block_length = 0;
while (file_block_length = fread (buffer, sizeof (char), buffer_size, FP) > 0) {
printf ("File_block_length =%d\n", file_block_length); Sending the string in buffer to New_server_socket is actually sent to the client if (send New_server_socket, buffer, file_block_length
, 0) < 0) {printf ("Send file:\t%s failed!\n", file_name); BReak;
bzero (buffer, sizeof (buffer));
Fclose (FP);
printf ("file:\t%s Transfer finished!\n", file_name);
Close (New_server_socket);
Close (Server_socket);
return 0; }
FILE_CLIENT.C Socket transfer File client-side sample program//////// #include <netinet/in.h>//For Sockaddr_i n #include <sys/types.h>//for socket #include <sys/socket.h> For socket #include <stdio.h>/for printf #include <stdli
B.h>//For exit #include <string.h>//For Bzero #define HELLO_WORLD_SERVER_PORT 6666 #define BUFFER_SIZE 1024 #define File_
name_max_size int main (int argc, char **argv) {if (argc!= 2) {
printf ("Usage:./%s serveripaddress\n", argv[0]);
Exit (1); //Set a socket address structure CLIENT_ADDR, Representative guestThe Internet address and port struct sockaddr_in client_addr of the household machine;
Bzero (&client_addr, sizeof (CLIENT_ADDR)); client_addr.sin_family = af_inet; Internet Protocol Family client_addr.sin_addr.s_addr = htons (Inaddr_any); Inaddr_any means to automatically obtain the native address Client_addr.sin_port = htons (0); Auto allocated, let the system automatically assign an idle port//To create a streaming protocol (TCP) type socket for the Internet, using Client_socket to represent the client socket int
Client_socket = socket (af_inet, sock_stream, 0);
if (Client_socket < 0) {printf ("Create socket failed!\n");
Exit (1); //Bind the socket of the client to the socket address structure of the client if (bind Client_socket, (struct sockaddr*) &client_addr,
sizeof (CLIENT_ADDR))) {printf ("Client Bind Port failed!\n");
Exit (1);
//Set a socket address structure server_addr, representing the server's Internet address and port struct sockaddr_in server_addr; Bzero (&server_addr, sizeof (serveR_ADDR));
server_addr.sin_family = af_inet; The IP address of the server comes from the parameter of the program if (Inet_aton (argv[1], &server_addr.sin_addr) = = 0) {printf ("Se
RVer IP address error!\n ");
Exit (1);
} Server_addr.sin_port = Htons (Hello_world_server_port);
socklen_t server_addr_length = sizeof (SERVER_ADDR); Initiates a connection request to the server, Client_socket on behalf of a socket connection on the client and server side if (connect (client_socket, struct sockaddr*) &server_a
DDR, Server_addr_length) < 0) {printf ("Can not Connect to%s!\n", argv[1]);
Exit (1);
} char file_name[file_name_max_size + 1];
Bzero (file_name, sizeof (file_name));
printf ("Please Input File Name on server.\t");
scanf ("%s", file_name);
Char Buffer[buffer_size];
bzero (buffer, sizeof (buffer)); strncpy (buffer, file_name, strlen (file_name) > Buffer_size?
Buffer_size:strlen (file_name));
Send data to the server in buffer, at this time buffer is stored in the client needs to receive the file name send (client_socket, buffer, buffer_size, 0);
FILE *FP = fopen (file_name, "w");
if (fp = = NULL) {printf ("file:\t%s Can not Open to write!\n", file_name);
Exit (1);
///Receive data from server side to buffer bzero (buffer, sizeof (buffer));
int length = 0;
while (length = recv (client_socket, buffer, buffer_size, 0)) {if (length < 0) {
printf ("Recieve Data from Server%s failed!\n", argv[1]);
Break
int write_length = fwrite (buffer, sizeof (char), length, FP);
if (Write_length < length) {printf ("file:\t%s write failed!\n", file_name);
Break } bzero (Buffer, Buffer_SIZE);
printf ("Recieve file:\t%s from server[%s] finished!\n", file_name, argv[1]);
Transfer complete, close socket fclose (FP);
Close (Client_socket);
return 0;
}
2. Use of existing communication middleware 2.1 ActiveMQ Transfer File interface
In order to solve the problem of transferring large files, ACTIVEMQ introduced the concept of JMS streams outside the JMS specification. In PTP mode, connected to both ends of the same destination, you can transfer large files via broker relay.
The sender uses Connection.createoutputstream to open an output stream and write files to the stream.
OutputStream out =connection.createoutputstream (destination);
The receiving end simply uses Connection.createinputstream to get an input stream from which to read the file data.
InputStream in = Connection.createinputstream (destination)
See: http://activemq.apache.org/jms-streams.html
2.2 ZeroMQ Interface
ZEROMQ does not provide a direct interface for transferring files. However, the ZEROMQ send (void * data, size_t len) interface has been packaged to send data of any size. The code is as follows:
zmq::context_t CTX (1);
zmq::socket_t sock (CTX, zmq_req);
Sock.connect ("tcp://192.168.20.111:20310");
Sock.send (Pdata,len);//data size is not limited, you can directly send arbitrary size data
char reply[100];
SOCK.RECV (reply,100);
Sock.disconnect (addr);
The receiving end code is as follows:
M_context = new zmq::context_t (1);
M_socket = new zmq::socket_t (*m_context, zmq_rep);
M_socket->bind ("tcp://*:20310");
zmq::message_t request;
Wait to next request from client
M_SOCKET->RECV (&request)//request can accept data of any size sent
m_socket-> Send ("OK", 2);
Is it simple?
3. Based on shared files, FTP, SCP, etc.
This is not to elaborate. Either write a shared directory or call a system command.
4. Summary
1) is more difficult to program directly based on the socket, so it is not recommended.
2) is convenient to use an existing library, but needs to be learned. General recommendation.
3) The difficulty of sharing files, FTP, SCP, and so on, is simple and easy to use, and is preferred when using scenarios. (But some pretentious programmers may scoff at you and consider ...) )