C++和java通过Socket批量发送和接收文件(C++客户端发送,java服务端接收)

基本思路是: C++扫描目录下存在多少个文件,先发送文件的数目,然后循环发送每个文件。

发送每个文件的时候,先发送文件名和文件大小,收到确认回复后再发送文件数据。


C++客户端代码:

#include <Winsock2.h>  
#include <cstdio>  
#include <fstream>  
#include<string>
#include<vector>
#include<io.h>
#pragma comment(lib,"ws2_32.lib")  
using namespace std;

size_t getSize(string path)
{
	FILE * file;
	file = fopen(path.c_str(), "rb");
	size_t sizeOfPic;

	fseek(file, 0, SEEK_END);   ///将文件指针移动文件结尾  
	sizeOfPic = ftell(file); ///求出当前文件指针距离文件开始的字节数  
	fclose(file);

	return sizeOfPic;
}

void getFiles(std::string path, vector<std::string>& files)
{
	//文件句柄  
	long   hFile = 0;
	//文件信息  
	struct _finddata_t fileinfo;
	string p;
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
	{
		do
		{
			//如果是目录,迭代之  
			//如果不是,加入列表  
			if ((fileinfo.attrib &  _A_SUBDIR))
			{
				if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
					getFiles(p.assign(path).append("\\").append(fileinfo.name), files);
			}
			else
			{
				files.push_back(p.assign(path).append("\\").append(fileinfo.name));
			}
		} while (_findnext(hFile, &fileinfo) == 0);
		_findclose(hFile);
	}
}

void main()
{
	WSADATA wsaData;
	SOCKET sockClient;//客户端Socket  
	SOCKADDR_IN addrServer;//服务端地址  
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	//新建客户端socket  
	sockClient = socket(AF_INET, SOCK_STREAM, 0);
	//定义要连接的服务端地址  
	addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//目标IP(127.0.0.1是回送地址)  
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(8089);//连接端口6000  
	//连接到服务端  
	connect(sockClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
	//发送数据  
	//  char message[20] = "HelloSocket!";  
	char recvBuf[30];
	char size[20];

	string path = "C:\\Release\\Audio\\";
	vector<string> files;
	getFiles(path, files);

	if (files.size() > 0)
	{
		//发送文件数量
		char file_num[256];
		sprintf(file_num, "%d", files.size());
		send(sockClient, file_num, strlen(file_num), 0);
		//服务端确认收到
		int numRecv_size;
		char numBuf[1024];
		numRecv_size = recv(sockClient, numBuf, 1024, 0);
		char* numRecv = new char[numRecv_size + 1];
		for (int i = 0; i < numRecv_size; i++)
			numRecv[i] = numBuf[i];
		numRecv[numRecv_size] = '\0';

		if (strcmp(numRecv, "num_recv") == 0)
		{
			for (auto it = files.begin(); it != files.end(); it++)
			{
				//发送文件名
				size_t pos;
				pos = it->find_last_of("/\\");
				if (pos == string::npos)
				{
					break;
				}
				string file_str = it->substr(pos + 1);
				char file_buf[256];
				sprintf(file_buf, "%s", file_str.c_str());
				send(sockClient, file_buf, strlen(file_buf), 0);
				//服务端确认收到
				int nameRecv_size;
				char nameBuf[1024];
				nameRecv_size = recv(sockClient, nameBuf, 1024, 0);
				char* nameRecv = new char[nameRecv_size + 1];
				for (int i = 0; i < nameRecv_size; i++)
				{
					nameRecv[i] = nameBuf[i];
				}
				nameRecv[nameRecv_size] = '\0';
				if (strcmp(nameRecv, "name_recv") != 0)
					break;

				//发送文件大小
				int fileSize = getSize(*it);
				char file_size[256];
				sprintf(file_size, "%d", fileSize);
				send(sockClient, file_size, strlen(file_size), 0);
				//服务端确认收到
				int sizeRecv_size;
				char sizeBuf[1024];
				sizeRecv_size = recv(sockClient, sizeBuf, 1024, 0);
				char* sizeRecv = new char[sizeRecv_size + 1];
				for (int i = 0; i < sizeRecv_size; i++)
					sizeRecv[i] = sizeBuf[i];
				sizeRecv[sizeRecv_size] = '\0';
				if (strcmp(sizeRecv, "size_recv") != 0)
					break;

				FILE * file;
				file = fopen(it->c_str(), "rb");
				char buf[1024];
				while (!feof(file))
				{
					memset(buf, 0, sizeof(buf));
					size_t readlen = fread(buf, sizeof(char), sizeof(buf), file);
					send(sockClient, buf, readlen, 0);
				}
				//		send(sockClient, "completed", strlen("completed"), 0);
				fclose(file);
			}
		}
		

		
	}
	
	//关闭socket  
	closesocket(sockClient);
	
	WSACleanup();
}

Java服务端代码:

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class FileServer implements Runnable {

    @Override
    public void run() {

    }

    public static void main(String[] args) {
        try {
            final ServerSocket server = new ServerSocket(8089);
            Thread th = new Thread(new Runnable() {

                @Override
                public void run() {
                    while (true) {
 //                   	Socket socket;
                        try {
                           System.out.println("开始监听。。。");
                           Socket socket = server.accept();
                           System.out.println("有链接");
                           receiveFile(socket);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    
                    }

                }

            });
            th.run();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

	public static void receiveFile(Socket socket) throws IOException {
        byte[] inputByte = null;
        int length = 0;
        DataInputStream din = null;
        DataOutputStream dout = null;
        FileOutputStream fout = null;
 
        try {
            din = new DataInputStream(socket.getInputStream());
            dout = new DataOutputStream(socket.getOutputStream());
            
            //接收文件数量
            byte[] numByte = new byte[256];
            int file_num = din.read(numByte);
            byte[] NumByte = new byte[file_num];
            for(int i=0;i<file_num;i++)
            {
            	NumByte[i] = numByte[i];
            }
            String fileNumStr = new String(NumByte);
            int fileNum = Integer.parseInt(fileNumStr);
            if(fileNum>0)
            {
            	//回复确认
            	String num_back = "num_recv";
            	byte[] num_back_byte = num_back.getBytes();
            	dout.write(num_back_byte,0,num_back.length());
//            	dout.writeBytes(num_back);
            	
            	 for(int index=0;index<fileNum;index++)
                 {
                 	//接收文件名
            		 byte[] nameByte = new byte[256];
                     int file_name_len = din.read(nameByte);
 //                    din.read()
                     byte[] NameByte = new byte[file_name_len];
                     for(int i=0;i<file_name_len;i++)
                     {
                     	NameByte[i] = nameByte[i];
                     }
                     System.out.println(NameByte);
                     String file_name = new String(NameByte);
                     System.out.println(file_name);
                     String file_path = "C:\\Release\\received\\"+file_name;
                     System.out.println(file_path);
                     //回复确认
                     String name_back = "name_recv";
                 	 byte[] name_back_byte = name_back.getBytes();
                 	 dout.write(name_back_byte,0,name_back.length());
                 	
                 	//接收文件大小
                 	 byte[] sizeByte = new byte[256];
                     int file_size = din.read(sizeByte);
                     byte[] SizeByte = new byte[file_size];
                     for(int i=0;i<file_size;i++)
                     {
                     	SizeByte[i] = sizeByte[i];
                     }
                     String fileSizeStr = new String(SizeByte);
                     int fileSize = Integer.parseInt(fileSizeStr);
                     System.out.println(fileSize);
                     //回复确认
                     String size_back = "size_recv";
                 	 byte[] size_back_byte = size_back.getBytes();
                 	 dout.write(size_back_byte,0,size_back.length());
                     
                     File file = new File(file_path);
                     fout = new FileOutputStream(file);
//                     inputByte = new byte[1024];
                     System.out.println("开始接收数据...");
                     while (fileSize > 0) {
                         if (din != null) {
                        	 if(fileSize-1024<0)
                        		 inputByte = new byte[fileSize];
                        	 else
                        		 inputByte = new byte[1024];
                             length = din.read(inputByte, 0, inputByte.length);
                             
                         }
                         if (length == -1) {
                             break;
                         }
                         fout.write(inputByte, 0, length);
                         fileSize -= length;
                         fout.flush();
                     }
                     fout.close();
                 }
            }
            
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
//        	if (fout != null)
//                fout.close();
            if (din != null)
                din.close();
            if (socket != null)
                socket.close();
        }
    }

}


以下是使用C++和zmq实现dealer和router模式的客户端发送服务端接收的示例代码: 服务端代码: ```cpp #include <zmq.hpp> #include <iostream> int main() { zmq::context_t context(1); zmq::socket_t socket(context, zmq::socket_type::router); socket.bind("tcp://*:5555"); // 绑定端口 while (true) { zmq::message_t identity_msg, request_msg; socket.recv(&identity_msg); // 接收客户端的身份信息 socket.recv(&request_msg); // 接收客户端的请求消息 std::string identity(static_cast<char*>(identity_msg.data()), identity_msg.size()); std::string request(static_cast<char*>(request_msg.data()), request_msg.size()); std::cout << "Received request from " << identity << ": " << request << std::endl; // 回复客户端 zmq::message_t reply_msg(request.size()); memcpy(reply_msg.data(), request.data(), request.size()); socket.send(identity_msg, zmq::send_flags::sndmore); socket.send(reply_msg, zmq::send_flags::none); } return 0; } ``` 客户端代码: ```cpp #include <zmq.hpp> #include <iostream> int main() { const std::string endpoint = "tcp://localhost:5555"; zmq::context_t context(1); zmq::socket_t socket(context, zmq::socket_type::dealer); // 设置客户端的身份信息 std::string identity = "client1"; socket.setsockopt(ZMQ_IDENTITY, identity.data(), identity.size()); socket.connect(endpoint); // 发送请求消息 std::string request = "Hello, server!"; zmq::message_t request_msg(request.size()); memcpy(request_msg.data(), request.data(), request.size()); socket.send(request_msg, zmq::send_flags::none); // 接收回复消息 zmq::message_t identity_msg, reply_msg; socket.recv(&identity_msg); socket.recv(&reply_msg); std::string server_identity(static_cast<char*>(identity_msg.data()), identity_msg.size()); std::string reply(static_cast<char*>(reply_msg.data()), reply_msg.size()); std::cout << "Received reply from " << server_identity << ": " << reply << std::endl; return 0; } ``` 在上述代码中,服务端使用router模式,绑定端口并接收客户端的身份信息和请求消息,然后回复客户端客户端使用dealer模式,设置自己的身份信息后连接服务端发送请求消息并接收服务端的回复消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值