Answer the question
In order to leave comments, you need to log in
Why is the string split when transmitted over the socket?
There is a task to write an application (client-server) for transferring binary files. Wrote the following implementation:
Client
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <cstring>
#define IP "127.0.0.1"
#define PORT 27015
#define BUFSIZE 4096
#pragma comment(lib, "Ws2_32.lib")
void sendFile(SOCKET& client_socket, char* buf, char* filepath);
int main()
{
WSADATA d;
int result;
result = WSAStartup(MAKEWORD(2,2), &d);
if (result != 0)
{
std::cout << "Error WSAStartup: " << result << "\n";
return 1;
}
SOCKET clientSocket = INVALID_SOCKET;
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET)
{
std::cout << "Error socket(): " << WSAGetLastError() << "\n";
WSACleanup();
return 1;
}
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr(IP);
clientService.sin_port = htons(PORT);
result = connect(
clientSocket,
reinterpret_cast<SOCKADDR*>(&clientService),
sizeof(clientService)
);
if (result != 0)
{
std::cout << "Connection error: " << WSAGetLastError() << "\n";
WSACleanup();
return 1;
}
const int N = 100;
char buf[BUFSIZE], filepath[N];
int r;
do
{
std::cin >> filepath;
sendFile(clientSocket, buf, filepath);
if (r > 0)
std::cout << "Receive: " << buf << "\n";
else if (r == 0)
std::cout << "Connection lost\n";
else
std::cout << "Recv error: " << WSAGetLastError() << "\n";
} while (r > 0);
closesocket(clientSocket);
WSACleanup();
return 0;
}
void sendFile(SOCKET& clientSocket, char* buf, char* filepath)
{
FILE *f;
f = fopen(filepath, "rb");
int readed;
if (f != 0)
{
while((readed = fread(buf, 1, sizeof(buf), f)) != 0)
{
send(clientSocket, (char*)buf, readed, 0);
}
}
}
#define _WIN32_WINNT 0x501
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#define DEFAULT_PORT "27015"
#define DEFAULT_BUFLEN 4096
#pragma comment(lib, "Ws2_32.lib")
int main()
{
int iResult;
WSAData d;
// Данные для сокета
iResult = WSAStartup(MAKEWORD(2,2), &d);
if (iResult != 0)
{
std::cout << "Error at WSAStartup: " << iResult;
return 1;
}
struct addrinfo *result = nullptr, hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0)
{
std::cout << "getaddrinfo error: " << iResult;
WSACleanup();
return 1;
}
// Creating socket
SOCKET listenSocket = INVALID_SOCKET;
listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (listenSocket == INVALID_SOCKET)
{
std::cout << "Error at socket(): " << WSAGetLastError();
freeaddrinfo(result);
WSACleanup();
return 1;
}
iResult = bind(listenSocket, result->ai_addr, result->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
std::cout << "Error at bind(): " << WSAGetLastError();
freeaddrinfo(result);
WSACleanup();
return 1;
}
freeaddrinfo(result);
if (listen(listenSocket, SOMAXCONN) == SOCKET_ERROR)
{
std::cout << "Listen error: " << WSAGetLastError();
closesocket(listenSocket);
WSACleanup();
return 1;
}
SOCKET ClientSocket = INVALID_SOCKET;
ClientSocket = accept(listenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET)
{
std::cout << "Accept failed with error: " << WSAGetLastError();
closesocket(listenSocket);
WSACleanup();
return 1;
}
// data trade
char recvbuf[DEFAULT_BUFLEN];
int iSendResult;
int recvbuflen = DEFAULT_BUFLEN;
do
{
iResult = recv(ClientSocket, recvbuf, sizeof(recvbuflen), 0);
FILE *f = fopen("output.txt", "wb");
fwrite(recvbuf, 1, iResult, f);
if (iResult > 0)
{
std::cout << "Recv: " << recvbuf << "\n";
iSendResult = send(ClientSocket, recvbuf, recvbuflen, 0);
if (iSendResult == SOCKET_ERROR)
{
std::cout << "Send failed with error: " << WSAGetLastError();
closesocket(ClientSocket);
WSACleanup();
return 1;
}
}
else if (iResult == 0)
std::cout << "Connection closed...\n";
else
{
std::cout << "Recv error: " <<WSAGetLastError();
closesocket(ClientSocket);
return 1;
}
} while(iResult > 0);
}
Recv: Hell
Recv: o, w
Recv: orld
Answer the question
In order to leave comments, you need to log in
Another "I did not read the manuals, pamagit" question.
Read Sneijder, J. "Efficient TCP/IP Programming".
In short, the send() and recv() functions do not guarantee that as many bytes will be written or read as you send them. You need to analyze the value returned by these functions - if it is 0 or < 0 - something has broken and you need to analyze errorno, otherwise, that's how many bytes were transferred.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question