参考自:http://blog.csdn.net/nupt123456789/article/details/8047619
Java客户端上传图片(文件)到c++服务器
主要思路:将所有的数据类型都转化为byte流,对byte进行传输,c++服务器使用char数组,java使用byte数组进行图片(文件)的传输。
传输过程(socket建立连接的条件下):
C++服务器
TAG.h
#pragma once
#define _TAG_H_
#ifdef _TAG_H_
#include<Windows.h>
#define BUF_LEN 2048
#define SendFile 0x01
#define StopSendFile 0x02
#define SendString 0x03
#define FileInfo 0x04
typedef struct
{
int ID;
BYTE lparam[BUF_LEN];
}COMMAND;
typedef struct {
long fileLenght;
char fileName[MAX_PATH];
}FILEINFO;
#endif // _TAG_H_
SocketHead.h
#pragma once
#include <winsock2.h>
using namespace std;
#pragma comment(lib, "WS2_32") // 链接到WS2_32.lib
class CInitSock
{
public:
CInitSock(BYTE minorVer = 2, BYTE majorVer = 2)
{
// 初始化WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer, majorVer);
if (::WSAStartup(sockVersion, &wsaData) != 0)
{
exit(0);
}
}
~CInitSock()
{
::WSACleanup();
}
};
CPlusServer.cpp
// CPlusServer.cpp : 定义控制台应用程序的入口点。
//
/*
author:chenjianrun
time: 2016-9-15
city: zhuhai
*/
#include "stdafx.h"
#include"SocketHead.h"
#include "iostream"
#include "string.h"
#include "fstream"
#include<string>
#include"TAG.h"
using namespace std;
//初始化结构体SOCKADDR_IN
sockaddr_in initSockaddr_in();
//监听线程
DWORD WINAPI SListen(LPVOID lparam);
//接收文件
void recvFile(SOCKET socket);
//初始化socket
void InitSocket();
CInitSock initsocket;
int main()
{
InitSocket();
return 0;
}
void InitSocket() {
SOCKET serverSocket;
SOCKET listenSocket;
sockaddr_in serveraddr = initSockaddr_in();
sockaddr_in clientaddr;
//创建socket
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//进行绑定
bind(serverSocket, (sockaddr*)&serveraddr, sizeof(serveraddr));
//进行监听
listen(serverSocket, 5);
cout << "server start" << endl;
int len = sizeof(clientaddr);
while (true) {
if (listenSocket = accept(serverSocket, (sockaddr*)&clientaddr, &len));
{
//启动会话线程
CreateThread(NULL, NULL, SListen, (LPVOID)listenSocket, NULL, NULL);
cout << "CreateThread is start"<<endl;
}
}
}
sockaddr_in initSockaddr_in() {
sockaddr_in sockaddr_in;
int port = 8888;
sockaddr_in.sin_family = AF_INET;
sockaddr_in.sin_port = htons(port);//主机字节序转网络字节序
sockaddr_in.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
return sockaddr_in;
}
DWORD WINAPI SListen(LPVOID lparam) {
SOCKET socket = (SOCKET)lparam;
COMMAND command;
while (true) {
memset(&command, 0, sizeof(command));
int ret;
ret = recv(socket, (char*)&command, sizeof(command), 0);
if (ret == SOCKET_ERROR)
{
cout << "Client is close!"<<endl;
break;
}
else{
cout << "接收到命令:" << command.ID << endl;
switch (command.ID)
{
case FileInfo:
break;
case SendFile:
{
char* str = (char*)command.lparam;
cout << "原文件名" << str<< endl;
//开始接收文件
recvFile(socket);
}
break;
case StopSendFile:
break;
case SendString:
break;
default:
break;
}
}
}
return 0;
}
void recvFile(SOCKET socket) {
int ret;
char buffer[BUF_LEN];
//接收文件长度
long long fileLenght;
ret =