Я некоторое время застрял в этой проблеме, где я не могу отправить файл через сокет. Я просто передал другую информацию, используя этот метод, но проблема возникает, когда я пытаюсь отправить PNG-файл в виде строки.Ошибка сокета при отправке файла
Это методы, которые я использую, чтобы отправлять и получать информацию:
// Sends a Message to the specified Socket
void Server::sendMessage(int socket, string message)
{
// Write the Message Size to the Socket
send(socket, itoa((message.length() + 1)), sizeof(size_t));
// Wait for Write Confirmation
bool response;
receive(socket, &response, 2);
// Write the Message to the Socket
send(socket, (char*) message.c_str(), message.length() + 1);
// Wait for Write Confirmation
receive(socket, &response, 2);
}
// Receives Message from the specified Socket
string Server::receiveMessage(int socket)
{
// Read the Message Size from the Socket
int size;
receive(socket, &size, sizeof(size_t));
// Send Write Confirmation
send(socket, itoa(true), 2);
// Receive the Message from the Socket
char message[size];
receive(socket, message, size);
// Send Write Confirmation
send(socket, itoa(true), 2);
// Return the Message as a String
string msg(message);
return msg;
}
отправить и получить методы только реле для записи и чтения соответственно. Я только делаю проверку ошибок в этих методах, и это отправьте метод, который говорит мне, что пишет не работает. В случае, если это имеет значение, это мой отправить метод:
// Sends a Data Packet to the specified Socket
int Server::send(int socket, void* data, int size)
{
// Write the Data to the Socket
int count = write(socket, data, size);
// Make sure the Write Succeeded
if(count == -1)
{
print("$f1Error: $f0Unable to Write to Socket $t1%i$t0\n", socket);
exit(1);
}
return count;
}
Я хотел бы отметить, что сервер работает как Thread, поэтому приведенные выше три функции являются статическими. Клиент также содержит те же четыре сетевых функции.
Командная строка, разбивающая это, происходит в отдельной статической функции, которую я использую для обработки клиентов. Вот соответствующая часть указанного способа:
// Handles each Client with a Thread
void* Server::server_handleClient(void* arg)
{
// Determine the Socket Descriptor
int socket = *((int*) arg);
free(arg);
// Create the Rover
Rover* rover = new Rover();
// Loop Indefinitely
while(true)
{
...
// Take a Picture and Send it
sendMessage(socket, rover -> takePicture());
...
}
// Delete the Rover
delete rover;
// Close the Socket
close(socket);
// Return a Successful Status
return (void*) new int(0);
}
Здесь вы можете увидеть, что я использую метод из другого класса я создал. Вот takePicture метод от Rover класса, который является, где я на самом деле захватить картину:
// Takes a Picture and Returns the Photo as a String
inline string Rover::takePicture()
{
// Open the Picture File
ifstream picture;
string filepath = "./Server/Pictures/" + getDirection() + ".png";
picture.open(filepath.c_str());
// Make sure the File Opened
if(!picture.is_open())
return "";
// Read the File into a String Buffer
stringstream buffer;
buffer << picture.rdbuf();
return buffer.str();
}
Таким образом, в общем, сервер получает изображение от Rover который затем посылает до Клиент. Когда я проверяю содержимое строки для фотографии, это все. Все возможные фотографии являются разумными по размеру (фотография, используемая для тестирования, составляет 674,962 байт, а размер отправляемого буфера составляет 674,963, что ожидается).
Я использовал эти методы для отправки различных сообщений, и все это отлично работало. Я могу отправить строки (Как «Hello World!») и целые числа просто отлично.
Есть ли что-то, что я делаю неправильно? Является ли файл, который я пытаюсь отправить просто слишком большим? Есть ли какая-то информация, которую мне не хватает? Мне нужна помощь ...
Edit: Я сделал несколько изменений, с небольшим прогрессом. Я сделал небольшое изменение команды sendMessage. Текущая проблема заключается в том, что изображение не отправляется должным образом.
Новый SendMessage функция: копия
// Sends a Message to the specified Socket
void Server::sendMessage(int socket, string message, bool data = false)
{
// Write the Message Size to the Socket
send(socket, itoa((message.length() + 1)), sizeof(size_t));
// Wait for Write Confirmation
bool response;
receive(socket, &response, 2);
// Determine the Type of Data to Send
if(data)
{
// Write the Message Data to the Socket
send(socket, (char*) message.data(), message.length() + 1);
}
else
{
// Write the Message to the Socket
send(socket, (char*) message.c_str(), message.length() + 1);
}
// Wait for Write Confirmation
receive(socket, &response, 2);
}
Клиента этой функции была обновлена, чтобы соответствовать, а также.
Теперь, когда мы работаем над получением файла PNG сохранен, вот функция, которая имеет дело с тем, как хорошо:
// Handles each Client with a Thread
void* Client::client_handleServer(void* arg)
{
// Define Socket Variables
int socket = *((int*) arg);
free(arg);
...
// Export the Picture to the Client's Directory
message = receiveMessage(socket);
ofstream picture;
picture.open("./Client/Pictures/Picture.png", std::ifstream::binary);
picture << message;
picture.close();
...
}
Вы не описали, что происходит с изображением на стороне клиента? почему вы отправляете message.length() + 1? – goldcode
Я отправляю сообщение до отправки сообщения, чтобы другая система знала, сколько читать. Что касается изображения на стороне клиента, запись на стороне сервера не удалась, поэтому клиент так и не получил его. Код показывает это, поскольку ошибка возникает только в том случае, если количество байтов, записанных в сокет, равно -1 (это означает, что запись не удалась). – Boom