Przesyłanie struktury

0

Witam. Mam dwa programy klient i serwer gdzie klient po połączeniu się z serwerem wysyła do niego strukturę ale okazuje się że coś jest nie tak przy próbie wyświetlenia zawartości struktury odebranej od klienta.
Rezultat serwera:

Bytes received: 40
recvbuf:
: 27
2: -54
3: Melodiazo
4: zo

A powinno być:

Bytes received: 40
recvbuf:
: 27
2: -54
3: Melodia
4: zo

Kod klienta:

#include <iostream>
#include <string>
#include <windows.h>


#pragma comment(lib,"WS2_32")

struct struktura {

	int liczba;//2
	int mozna;//2

	char tescik[7];//7
	char tescika[3];//3

};

int main() {

	WSADATA wsaData;
	SOCKET mainSocket;

	struktura kk;

	kk.liczba = 27;
	kk.mozna = -54;

	kk.tescik[0] = 'M';
	kk.tescik[1] = 'e';
	kk.tescik[2] = 'l';
	kk.tescik[3] = 'o';
	kk.tescik[4] = 'd';
	kk.tescik[5] = 'i';
	kk.tescik[6] = 'a';

	kk.tescika[0] = 'z';
	kk.tescika[1] = 'o';
	kk.tescika[2] = '\0';

	int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (result != NO_ERROR) {
		exit(-1);
	}

	mainSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (mainSocket == INVALID_SOCKET)
	{
		WSACleanup();
		exit(-1);
	}

	sockaddr_in service;
	memset(&service, 0, sizeof(service));
	service.sin_family = AF_INET;
	//service.sin_addr.s_addr = inet_addr("192.168.0.103");
	service.sin_addr.s_addr = inet_addr("192.168.0.106");//3
	//InetPton(AF_INET, _T("192.168.1.1"), &RecvAddr.sin_addr.s_addr);
	service.sin_port = htons(27015);//8888

	if (connect(mainSocket, (SOCKADDR*)& service, sizeof(service)) == SOCKET_ERROR)
	{
		WSACleanup();
		exit(-1);
	}


	int bytesSent;

	char* byteStream = (char*)&kk;
	//void* myPtr = &kk;

	for (int x = 0; x < 1; x++) {


		bytesSent = send(mainSocket, byteStream + '\0', (sizeof(struktura) * sizeof(TCHAR)), 0);
		printf("Bytes sent: %ld\n", bytesSent);
		Sleep(500);
	}

}

Kod serwera

#undef UNICODE

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>

// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"

struct struktura {

	int liczba;
	int mozna;

	char tescik[7];
	char tescika[3];

};

int __cdecl main(void)
{
	WSADATA wsaData;
	int iResult;

	SOCKET ListenSocket = INVALID_SOCKET;
	SOCKET ClientSocket = INVALID_SOCKET;

	struct addrinfo* result = NULL;
	struct addrinfo hints;

	int iSendResult;
	char recvbuf[DEFAULT_BUFLEN];
	int recvbuflen = DEFAULT_BUFLEN;

	// Initialize Winsock
	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != 0) {
		printf("WSAStartup failed with error: %d\n", iResult);
		return 1;
	}

	ZeroMemory(&hints, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags = AI_PASSIVE;

	// Resolve the server address and port
	iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
	if (iResult != 0) {
		printf("getaddrinfo failed with error: %d\n", iResult);
		WSACleanup();
		return 1;
	}

	// Create a SOCKET for connecting to server
	ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
	if (ListenSocket == INVALID_SOCKET) {
		printf("socket failed with error: %ld\n", WSAGetLastError());
		freeaddrinfo(result);
		WSACleanup();
		return 1;
	}

	// Setup the TCP listening socket
	iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
	if (iResult == SOCKET_ERROR) {
		printf("bind failed with error: %d\n", WSAGetLastError());
		freeaddrinfo(result);
		closesocket(ListenSocket);
		WSACleanup();
		return 1;
	}

	freeaddrinfo(result);

	iResult = listen(ListenSocket, SOMAXCONN);
	if (iResult == SOCKET_ERROR) {
		printf("listen failed with error: %d\n", WSAGetLastError());
		closesocket(ListenSocket);
		WSACleanup();
		return 1;
	}

	std::cout <<"Server is ready"<<std::endl;

	// Accept a client socket
	ClientSocket = accept(ListenSocket, NULL, NULL);
	if (ClientSocket == INVALID_SOCKET) {
		printf("accept failed with error: %d\n", WSAGetLastError());
		closesocket(ListenSocket);
		WSACleanup();
		return 1;
	}

	// No longer need server socket
	closesocket(ListenSocket);

	char data[4096];

	

	// Receive until the peer shuts down the connection
	do {

		iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);

		if (iResult > 0) {
			printf("Bytes received: %d\n", iResult);

			std::cout <<"recvbuf: "<< recvbuf <<std::endl;
			
			struktura* received = (struktura*)recvbuf;

			std::cout << "1: " << received->liczba << std::endl;
			std::cout << "2: " << received->mozna << std::endl;
			std::cout << "3: " << received->tescik << std::endl;
			std::cout << "4: " << received->tescika << std::endl;

			system("pause");

		}
		else if (iResult == 0)
			printf("Connection closing...\n");
		else {
			printf("recv failed with error: %d\n", WSAGetLastError());
			closesocket(ClientSocket);
			WSACleanup();
			return 1;
		}

	} while (iResult > 0);

	// shutdown the connection since we're done
	iResult = shutdown(ClientSocket, SD_SEND);
	if (iResult == SOCKET_ERROR) {
		printf("shutdown failed with error: %d\n", WSAGetLastError());
		closesocket(ClientSocket);
		WSACleanup();
		return 1;
	}

	// cleanup
	closesocket(ClientSocket);
	WSACleanup();

	return 0;
}
4

Pola struktury są ułożone w pamięci jedno za drugim. C-stringi są wypisywane aż do napotkanego znaku 0. Jeśli chcesz wypisać konkretną liczbę znaków to przekaż ją do funkcji wypisującej.

Przykład (dirty, ale działa)

            std::string temp(received->tescik, sizeof(struktura::tescik));
            std::cout << "3: " << temp << std::endl;

1 użytkowników online, w tym zalogowanych: 0, gości: 1