I can't send text file from client to server - c++

I'm using ubuntu 20.04 now. I have text file in client document. The server can listen the port and I can sen the file but when I open it, there is no text.
client code;
#include <iostream>
#include <string>
#include <cstring>
#include <fstream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
const int BUFSIZE = 4096;
int main(int argc, char *argv[]) {
int client_socket;
struct sockaddr_in server_address;
char buffer[BUFSIZE];
// Create a socket
client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket < 0) {
std::cerr << "Failed to create socket" << std::endl;
return 1;
}
// Set up the server address
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_port = htons(12345);
if (inet_aton("127.0.0.1", &server_address.sin_addr) == 0) {
std::cerr << "Invalid address" << std::endl;
return 1;
}
// Connect to the server
if (connect(client_socket, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
std::cerr << "Failed to connect to server" << std::endl;
return 1;
}
std::cout << "Connected to server at " << inet_ntoa(server_address.sin_addr) << ":" << ntohs(server_address.sin_port) << std::endl;
// Send the file
std::ifstream input_file("file_to_send.txt", std::ios::binary); //
int bytes_sent;
while (input_file.read(buffer, BUFSIZE)) {
bytes_sent = send(client_socket, buffer, input_file.gcount(), 0);
if (bytes_sent < 0) {
std::cerr << "Failed to send data" << std::endl;
break;
}
}
input_file.close();
close(client_socket);
std::cout << "File 'file_to_send.txt' sent" << std::endl;
return 0;
}
server code;
#include <iostream>
#include <string>
#include <cstring>
#include <fstream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
const int BUFSIZE = 4096;
int main(int argc, char *argv[]) {
int server_socket, client_socket;
struct sockaddr_in server_address, client_address;
socklen_t client_address_len;
char buffer[BUFSIZE];
// Create a socket
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
std::cerr << "Failed to create socket" << std::endl;
return 1;
}
// Set up the server address
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(12345);
// Bind the socket to the server address
if (bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
std::cerr << "Failed to bind socket" << std::endl;
return 1;
}
// Listen for incoming connections
if (listen(server_socket, 5) < 0) {
std::cerr << "Failed to listen on socket" << std::endl;
return 1;
}
std::cout << "Listening for incoming connections on port 12345.." << std::endl;
// Accept an incoming connection
client_address_len = sizeof(client_address);
client_socket = accept(server_socket, (struct sockaddr *) &client_address, &client_address_len);
if (client_socket < 0) {
std::cerr << "Failed to accept connection" << std::endl;
return 1;
}
std::cout << "Accepted connection from " << inet_ntoa(client_address.sin_addr) << std::endl;
// Receive the file
std::ofstream output_file("received_file.txt", std::ios::binary);
int bytes_received;
std::cout << "Bytes received: " << bytes_received << std::endl;
while( (bytes_received = recv(client_socket, buffer, BUFSIZE,0)))>0{
std::cout << "Bytses recieved are not null." << std::endl;
output_file.write(buffer , bytes_received); }
output_file.close();
close(client_socket);
close(server_socket);
std::cout << "File received and saved as 'received_file.txt'" << std::endl;
return 0;
}
I added sys/socket.h library but I think there is a problem in line 65. I ran the server and client. On terminaL, I see "Connected to server at" and "File 'file_to_send.txt' sent". And for server, I see "Listening for incoming connections on port","Accepted connection from ", "Bytes received: 0" and "File received and saved as 'received_file.txt'". "Hello world" is written in the text file I'm new to this topic so I don't know what to do properly. How can I handle this? Thank you.

Related

Simple non-blocking multi-threaded tcp server

I'm studying C++, and this weekend I started to play around with sockets and threads. Bellow is a simple multi threaded server that I'm making based on some tutorials.
The issue that I'm facing is that when I'm connecting with 2 telnet clients only the keystrokes form the first connection appear on the server. Any keystroke sent from the second telnet connection appears suddenly once the first telnet connection closes. Could someone explain to me what have I done wrong here?
#include <iostream>
#include <string>
#include <thread>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
void clientSocketHandler(SOCKET clientSocket, std::string client_ip) {
char buf[4096];
std::thread::id thread_id = std::this_thread::get_id();
std::cout << thread_id << " - " << client_ip << ": connected" << std::endl;
while (true)
{
ZeroMemory(buf, 4096);
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == 0)
{
std::cout << thread_id << " - " << client_ip << ": disconnected" << std::endl;
break;
}
if (bytesReceived > 0)
{
std::cout << thread_id << " - " << client_ip << ": " << std::string(buf, 0, bytesReceived) << std::endl;
//send(clientSocket, buf, bytesReceived + 1, 0);
}
}
std::cout << thread_id << " - " << client_ip << ": closing client socket & exiting thread..." << std::endl;
closesocket(clientSocket);
}
void waitForConnections(SOCKET serverSocket) {
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(1337);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(serverSocket, (sockaddr*)&hint, sizeof(hint));
listen(serverSocket, SOMAXCONN);
while (true) {
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(serverSocket, (sockaddr*)&client, &clientSize);
if (clientSocket != INVALID_SOCKET)
{
char host[NI_MAXHOST]; // Client's remote name
ZeroMemory(host, NI_MAXHOST); // same as memset(host, 0, NI_MAXHOST);
std::string client_ip = inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
std::thread t(clientSocketHandler, clientSocket, client_ip);
t.join();
}
Sleep(100);
}
}
int main()
{
// Initialze winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOk = WSAStartup(ver, &wsData);
if (wsOk != 0)
{
std::cerr << "Can't Initialize winsock! Quitting..." << std::endl;
return 1;
}
// Create a socket
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET)
{
WSACleanup();
std::cerr << "Can't create a socket! Quitting..." << std::endl;
return 1;
}
// If serverSocketMode = 0, blocking is enabled;
// If serverSocketMode != 0, non-blocking mode is enabled.
u_long serverSocketMode = 1;
if (ioctlsocket(serverSocket, FIONBIO, &serverSocketMode) != NO_ERROR)
{
WSACleanup();
std::cerr << "Can't set socket to non-blocking mode! Quitting..." << std::endl;
return 1;
}
// Disables the Nagle algorithm for send coalescing.
// This socket option is included for backward
// compatibility with Windows Sockets 1.1
BOOL flag = TRUE;
if (setsockopt(serverSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&flag, sizeof(flag)) != NO_ERROR)
{
WSACleanup();
std::cerr << "Can't set socket NO_DELAY option! Quitting..." << std::endl;
return 1;
}
// Start listening for connections
waitForConnections(serverSocket);
// Cleanup winsock
WSACleanup();
system("pause");
return 0;
}
This should work. I removed pointless things like setting the socket to non-blocking and disabling the Nagle algorithm. The latter should only be done for things that need low-millisecond interactivity.
But, the substantial change that should fix your problem is changing join to detach. Using join causes your program to wait for the thread to finish before continuing. Using detach says "This thread is going to run in the background doing things, and I don't care about learning its fate later.".
If you don't use one of the two, and the ::std::thread object is destroyed, the system throws an exception because you're destroying the only means you have of getting information about whether or not a thread exited with an error of some kind with saying that either you don't care about such information, or explicitly asking for it.
I don't have Windows, so I can't test it:
#include <iostream>
#include <string>
#include <thread>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
void clientSocketHandler(SOCKET clientSocket, std::string client_ip)
{
char buf[4096];
std::thread::id thread_id = std::this_thread::get_id();
std::cout << thread_id << " - " << client_ip << ": connected" << std::endl;
while (true)
{
ZeroMemory(buf, 4096);
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == 0)
{
std::cout << thread_id << " - " << client_ip << ": disconnected" << std::endl;
break;
}
if (bytesReceived > 0)
{
std::cout << thread_id << " - " << client_ip << ": " << std::string(buf, 0, bytesReceived) << std::endl;
//send(clientSocket, buf, bytesReceived + 1, 0);
}
}
std::cout << thread_id << " - " << client_ip << ": closing client socket & exiting thread..." << std::endl;
closesocket(clientSocket);
}
void waitForConnections(SOCKET serverSocket)
{
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(1337);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(serverSocket, (sockaddr*)&hint, sizeof(hint));
listen(serverSocket, SOMAXCONN);
while (true) {
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(serverSocket, (sockaddr*)&client, &clientSize);
if (clientSocket != INVALID_SOCKET)
{
char host[NI_MAXHOST]; // Client's remote name
ZeroMemory(host, NI_MAXHOST); // same as memset(host, 0, NI_MAXHOST);
std::string client_ip = inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
std::thread t(clientSocketHandler, clientSocket, client_ip);
t.detach();
}
Sleep(100);
}
}
int main()
{
// Initialze winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOk = WSAStartup(ver, &wsData);
if (wsOk != 0)
{
std::cerr << "Can't Initialize winsock! Quitting..." << std::endl;
return 1;
}
// Create a socket
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET)
{
WSACleanup();
std::cerr << "Can't create a socket! Quitting..." << std::endl;
return 1;
}
// Start listening for connections
waitForConnections(serverSocket);
// Cleanup winsock
WSACleanup();
system("pause");
return 0;
}

Sending and Receiving From a Server Simultaneously

The way my code is currently written only allows a message from the server to be read directly after input is taken and a message is sent. However, this code is for a chat server and must allow a read to occur at any time a message is sent.
#include <iostream>
#include <string>
#include <cstring>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_ADDRESS "127.0.0.1"
constexpr int server_port = 15555;
#define SERVER_SUCCESS "1"
#define SERVER_FAILURE "-1"
constexpr int msg_buffer_size = 4096;
int main(int argc, char *argv[])
{
struct sockaddr_in serv_addr;
int sock;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
std::cerr << "Socket creation failed!" << std::endl;
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(server_port);
if (inet_pton(AF_INET, SERVER_ADDRESS, &serv_addr.sin_addr) <= 0)
{
std::cerr << "Invalid server address!" << std::endl;
return 1;
}
if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
std::cerr << "Failed to connect to chat server!" << std::endl;
return 1;
}
int valread;
while (true)
{
std::cout << ">> ";
char msg[msg_buffer_size];
char return_msg[msg_buffer_size];
std::string input;
std::getline(std::cin, input);
if (input == "quit")
return 0;
if (input.length() > 4000)
{
std::cout << "Input length must be less than 4000 characters." << std::endl;
continue;
}
strcpy(msg, input.c_str());
if (send(sock, msg, strlen(msg), 0) < 0)
{
std::cout << "Error sending data." << std::endl;
continue;
}
if (recv(sock, return_msg, msg_buffer_size, 0) < 0)
{
std::cout << "Error receiving data." << std::endl;
continue;
}
std::string code(strtok(return_msg, " "));
if (code == SERVER_FAILURE)
std::cout << "Failure: " << strtok(NULL, "") << std::endl;
else
std::cout << strtok(NULL, "") << std::endl;
memset(msg, 0, msg_buffer_size);
memset(return_msg, 0, msg_buffer_size);
}
std::cout << "Exiting." << std::endl;
close(sock);
return 0;
}
What would be a correct way to allow the client to receive a message as soon as one is sent from the server? I was thinking about making a thread, but it seemed kind of redundant since I would be receiving in two places.

Socket consistently disconnecting C++

I have a client and server set up to talk to each other. But every time I try to echo back to the client the socket seems to have disconnected. Much of the code is adapted from a sockets tutorial over at yolinux. Also, I'm running this remotely over ssh.
Client:
#include <cerrno>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/select.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <iostream>
#include <cstdlib>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <string>
#include <sstream>
using namespace std;
main(int argc, char *argv[])
{
if (argc != 3) {
cout << "exiting\n";
exit(EXIT_FAILURE);
}
struct sockaddr_in remoteSocketInfo;
struct hostent *hPtr;
int socketHandle;
char *remoteHost = argv[1];
int portNumber = atoi(argv[2]);
cout << "Welcome!\n";
// create socket
if ((socketHandle = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
{
cout << "Socket creation failed.\n";
close(socketHandle);
exit(EXIT_FAILURE);
}
cout << "Socket created!\n";
bzero(&remoteSocketInfo, sizeof(sockaddr_in)); // Clear structure memory
if ((hPtr = gethostbyname(remoteHost)) == NULL)
{
cerr << "System DN name resolution not configured properly.\n";
cerr << "Error number: " << ECONNREFUSED << endl;
exit(EXIT_FAILURE);
}
// Load system information for remote socket server into socket data structures
memcpy((char*)&remoteSocketInfo.sin_addr, hPtr->h_addr, hPtr->h_length);
remoteSocketInfo.sin_family = AF_INET;
remoteSocketInfo.sin_port = htons((u_short)portNumber); // set port number
if (connect(socketHandle, (struct sockaddr *)&remoteSocketInfo, sizeof(sockaddr_in)) < 0) {
cout << "connection failed\n";
close(socketHandle);
exit(EXIT_FAILURE);
}
cout << "Connected!\n";
string input;
int message;
while (1) {
cout << "Please indicate rotation amount:";
cin >> input;
if (input == "exit") {
close(socketHandle);
break;
}
char buf[input.length()+1];
const char *conv_input = input.c_str();
strcpy(buf, conv_input);
int bytes_sent = 0;
if ( (bytes_sent = send(socketHandle, buf, strlen(buf)+1, 0)) < 0) {
char buffer[256];
char * errorMessage = strerror_r( errno, buffer, 256);
cout << errorMessage << endl;
close(socketHandle);
exit(EXIT_FAILURE);
}
cout << "bytes sent: " << bytes_sent << endl;
int rc;
char buf2[input.length()+1];
rc = recv(socketHandle, buf2, strlen(buf)+1, 0);
buf[rc] = (char)NULL; // Null terminate string
cout << "received: " << buf2 << endl;
cout << "bytes received: " << rc << endl;
}
close(socketHandle);
}
Server:
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <strings.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstring>
#define MAXHOSTNAME 256
using namespace std;
main(int argc, char *argv[])
{
if (argc != 2) {
cout << "not enough arguments, ex: ./CaesarCipherServer 9876\n";
exit(EXIT_FAILURE);
}
struct sockaddr_in socketInfo;
char sysHost[MAXHOSTNAME+1]; // Hostname of this computer we're running on
struct hostent *hPtr;
int portNumber = atoi(argv[1]);
int sock;
bzero(&socketInfo, sizeof(sockaddr_in)); // Clear structure memory
// Get system information
gethostname(sysHost, MAXHOSTNAME); // Get this computer's hostname
if ((hPtr = gethostbyname(sysHost)) == NULL)
{
cerr << "System hostname misconfigured." << endl;
exit(EXIT_FAILURE);
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
close(sock);
exit(EXIT_FAILURE);
}
// Load system info into socket data structures
socketInfo.sin_family = AF_INET;
socketInfo.sin_addr.s_addr = htonl(INADDR_ANY); // Use any addr available
socketInfo.sin_port = htons(portNumber); // Set port number
// Bind the socket to a local socket address
if (bind(sock, (struct sockaddr *) &socketInfo, sizeof(socketInfo)) < 0)
{
close(sock);
perror("bind");
exit(EXIT_FAILURE);
}
cout << "listening for initial connection \n";
listen(sock, 1);
int sockConn;
if ((sockConn = accept(sock, NULL, NULL)) < 0)
{
exit(EXIT_FAILURE);
} else {
cout << "connection accepted!\n";
}
int rc = 0;
char buf[512];
cout << "about to receive message... \n";
// rc is number of chars returned
rc = recv(sockConn, buf, 512, 0);
buf[rc] = (char)NULL; // Null terminate string
cout << "received: " << buf << endl;
cout << "rc: " << rc << endl;
int bytes_sent;
if ((bytes_sent = send(sock, buf, rc, MSG_NOSIGNAL)) < 0) {
cout << "error sending\n";
close(sock);
exit(EXIT_FAILURE);
}
cout << "bytes sent: " << bytes_sent << endl;
close(sock);
}
Client Output:
./CaesarCipherClient cs-ssh 9876
Welcome!
Socket created!
socket handle : 3
Connected!
Please indicate rotation amount:5
bytes sent: 2
received:
bytes received: 0
Please indicate rotation amount:
Server Output:
./CaesarCipherServer 9876
listening for initial connection
connection accepted!
about to receive message...
received: 5
rc: 2
error sending
If the MSG_NOSIGNAL flag isn't specified, the server crashes at send(), which means the socket has disconnected at the other end. Why would the socket consistently disconnect after a send()/recv() pair?
I apologize for any poor readability/style/pure stupidity in my submission.
Thank you for your help!
In your server, you are using:
if ((bytes_sent = send(sock, buf, rc, MSG_NOSIGNAL)) < 0) {
cout << "error sending\n";
close(sock);
exit(EXIT_FAILURE);
}
Here, sock is the listening socket, not the accepted client socket. You need to replace sock with sockCon instead (which you are using in your recv() function call, and that is working).

Error in connecting sockets in c++

I am using this code snippet from an internet website, and according to it, this code works fine. But I'm unable to connect to server. Code and error are given below:
This is the code:
#include <iostream>
#include <winsock2.h>
#include <string>
#include <conio.h>
int main()
{
WSAData version; //We need to check the version.
WORD mkword = MAKEWORD(2, 2);
int what = WSAStartup(mkword, &version);
if (what != 0){
std::cout << "This version is not supported! - \n" << WSAGetLastError() << std::endl;
}
else{
std::cout << "Good - Everything fine!\n" << std::endl;
}
SOCKET u_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (u_sock == INVALID_SOCKET)
std::cout << "Creating socket fail\n";
else
std::cout << "It was okay to create the socket\n";
//Socket address information
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("10.3.34.131");
addr.sin_port = htons(80);
/*==========Addressing finished==========*/
//Now we connect
int conn = connect(u_sock, (SOCKADDR*)&addr, sizeof(addr));
if (conn == SOCKET_ERROR){
std::cout << "Error - when connecting " << WSAGetLastError() << std::endl;
closesocket(u_sock);
WSACleanup();
}
//Send some message to remote host
char* mymsg = "success";
char vect[512] = { 0 };
int smsg = send(u_sock, mymsg, strlen(mymsg), 0);
if (smsg == SOCKET_ERROR){
std::cout << "Error: " << WSAGetLastError() << std::endl;
WSACleanup();
}
int get = recv(u_sock, vect, 512, 0);
if (get == SOCKET_ERROR){
std::cout << "Error in Receiving: " << WSAGetLastError() << std::endl;
}
std::cout << vect << std::endl;
closesocket(u_sock);
_getch();
return 0;
}
This is the error:
How can I correct this error?
Your network has no machine with IP address 10.3.34.131 that is listening on port 80. Or, if it does, that machine is rejecting your machine's connections to it.

Difficulties decoding received (inner)packet

I'm building a ping function that, based on a destination and maximum number of hops, tries to reach the destination and report the stats of the response.
However I seem to have some difficulties decoding the received packet and extracting ttl, icmp-type and icmp-code and identification of the inner ip-packet. I'd also like to be able to set the identification of the transmitted packet, read the source port of the inner udp-packet or other means to identify packets for this function.
TL;DR
I'm struggeling and need help with:
Extracting ttl, icmp-type and icmp-code from received packet;
Extracting identification from received inner packet;
Setting identification of transmitted packet, read the source port of the inner udp-packet or other means to identify packets for this function.
Source:
#define SOCKET_ERROR -1
#include <cstdlib> //EXIT_SUCCES & EXIT_FAILURE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/ip.h> //iphdr
#include <netinet/ip_icmp.h> //icmphdr
#include <netinet/in.h> //sockaddr, sockaddr_in
#include <sys/socket.h>
#include <unistd.h>
//Additional network headers (taken from boost 1.53.0)
#include "../includes/icmp_header.hpp"
#include "../includes/ipv4_header.hpp"
int perform_ping(const char *destination, int max_hops) {
int msg_size = 32;
int transmission_socket;
if ((transmission_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR) {
printf("Failed to setup transmission socket.\n");
return EXIT_FAILURE;
}
int receiver_socket;
if ((receiver_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP)) == SOCKET_ERROR) { //Non-Priviledged
printf("Failed to setup receiver socket.\n");
return EXIT_FAILURE;
}
struct timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if (setsockopt(receiver_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) == SOCKET_ERROR) {
printf("Failed to setup receiver socket with timeout: %ld.%06d\n", timeout.tv_sec, timeout.tv_usec);
return EXIT_FAILURE;
}
struct sockaddr_in destination_address;
destination_address.sin_addr.s_addr = inet_addr(destination);
destination_address.sin_family = AF_INET;
destination_address.sin_port = htons(33434);
if (setsockopt(transmission_socket, IPPROTO_IP, IP_TTL, (char *)&max_hops, sizeof(max_hops)) == SOCKET_ERROR) {
printf("Failed to setup transmission socket with max_hops: %d\n", max_hops);
return EXIT_FAILURE;
}
char *transmission_buffer = NULL;
transmission_buffer = new char [sizeof (icmp) + msg_size];
int bytes_send = sendto(transmission_socket, transmission_buffer, sizeof(icmp) + msg_size, 0, (struct sockaddr *)&destination_address, sizeof(struct sockaddr_in));
if (bytes_send == SOCKET_ERROR) {
printf("An error has occured while sending: %s.", strerror(errno));
delete transmission_buffer;
return EXIT_FAILURE;
}
char *response_buffer;
if ((response_buffer = (char *)malloc(sizeof(struct ip) + sizeof(struct icmp))) == NULL) {
fprintf(stderr, "Could not allocate memory for packet\n");
return EXIT_FAILURE;
}
struct sockaddr remoteAddr;
socklen_t remoteAddrLen = sizeof(remoteAddr);
int bytes_received = recvfrom(receiver_socket, response_buffer, sizeof(ip) + sizeof(icmp), 0, &remoteAddr, &remoteAddrLen);
if (bytes_received != SOCKET_ERROR) {
printf("%s (%d)\n", inet_ntoa(((struct sockaddr_in *)&remoteAddr)->sin_addr), max_hops);
struct ip *ipheader = (struct ip *)response_buffer;
struct icmp *icmpheader = (struct icmp *)(response_buffer + sizeof(struct ip));
std::cout << "ip_ttl : " << std::dec << ipheader->ip_ttl << std::endl;
std::cout << "ip_ttl(hex): " << std::hex << ipheader->ip_ttl << std::endl;
std::cout << "ip_id : " << std::dec << ntohs(ipheader->ip_id) << std::endl;
std::cout << "ip_id(hex): " << std::hex << ntohs(ipheader->ip_id) << std::endl;
std::cout << "icmp_id : " << std::dec << ntohs(icmpheader->icmp_hun.ih_idseq.icd_id) << std::endl;
std::cout << "icmp_id(hex): " << std::hex << icmpheader->icmp_hun.ih_idseq.icd_id << std::endl;
std::cout << "icmp_type : " << std::dec << icmpheader->icmp_type << std::endl;
std::cout << "icmp_type(hex): " << std::hex << icmpheader->icmp_type << std::endl;
std::cout << "icmp_code : " << std::dec << icmpheader->icmp_code << std::endl;
std::cout << "icmp_code(hex): " << std::hex << icmpheader->icmp_code << std::endl;
} else {
printf("Socket error\n");
free(response_buffer);
return EXIT_FAILURE;
}
delete transmission_buffer;
free(response_buffer);
return EXIT_SUCCESS;
}
Received packet
ip (
identification: 0xe0ab (57515),
time to live: 250
),
icmp (
type: 11
code: 0
ip:(
identification: 0x7ec7 (32455),
time to live: 1
),
udp:(
source port: 56086
)
)
Expected output
90.145.29.174 (5)
ip_ttl : 250
ip_id : 32455
ip_id(hex): 7ec7
icmp_type: 11
icmp_code: 0
Actual output
90.145.29.174 (5)
ip_ttl : ? (actual question mark)
ip_ttl(hex): ? (action question mark)
ip_id : 57515
ip_id(hex): e0ab
icmp_type :
(newline)
icmp_type(hex):
(newline)
icmp_code :
icmp_code(hex):
PS: This is my first post, please forgive any mistakes :)