Socket server receiving data at buffer size - c++

I send packets of different sizes one after the other, how can I receive the packets separately at the size I send, not cumulated in the buffer. It seems that now the server adds to the buffer until it fills it and then I can process them.
Example:
Buffer size: 84.
Send from client: 84 bytes, 76 bytes, 76 bytes, 80 bytes
Receive in server: 84 bytes, 84 bytes, 84 bytes, 64 bytes.
I would like to receive them as I sent them. Is it possible?
int port = stoi(getConfig("server_port"));
std::string ipAddress = getConfig("ip_address");
// Create a socket
int listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening < 0){
std::cerr << "Can't create a socket!" << endl;
Logger("Can't create a socket!");
exit(-1);
}
std::cout << "The socket server was created successfully." << endl;
// Bind the socket to a IP / port
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
if (bind(listening, (sockaddr*)&hint, sizeof(hint)) < 0){
cerr << "Can't bind to IP/port!" << endl;
Logger("Can't bind to IP/port!");
exit(-1);
}
// Mark the socket for listening in
if (listen(listening, SOMAXCONN) < 0){
cerr << "Can't listen!" << endl;
Logger("Can't listen!");
exit(-1);
}
// Accept a call
sockaddr_in client;
socklen_t clientSize = sizeof(client);
char host[NI_MAXHOST];
char svc[NI_MAXSERV];
while(true){
int clientSoket = accept(listening, (sockaddr*)&client, &clientSize);
if(clientSoket < 0){
cerr << "Problem with client connecting!" << endl;
Logger("Problem with client connecting!");
break;
}
cout << "The client whas conected successfully." << endl;
memset(host, 0, NI_MAXHOST);
memset(svc, 0, NI_MAXSERV);
int result = getnameinfo((sockaddr*)&client, clientSize, host, NI_MAXHOST, svc, NI_MAXSERV, 0);
if(result == 0) {
cout << host << " connected on " << svc << endl;
} else {
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on " << ntohs(client.sin_port) << endl;
}
// While receiving
char buff[84];
while(true){
// Clear the buffer
memset(buff, 0, sizeof(buff));
// Wait for a message
int bytesRecv = recv(clientSoket, buff, sizeof(buff), 0);
if(bytesRecv < 0){
cerr << "There was a connection issue!" << endl;
Logger("There was a connection issue!");
break;
}
if(bytesRecv == 0){
cout << "The client disconnected." << endl;
Logger("The client disconnected");
break;
}
cout << "bytesRecv: " << bytesRecv << endl;
}
// Close the socket
close(clientSoket);
}

No, stream sockets don't work that way.
A stream socket is an unstructured byte stream, without any structure to it, whatsoever. In this respect it is no different from a plain file. If you wrote your records, of varying sizes, to a plain file and you are now prepared to read them back, how do you expect to read the your variably-sized records?
Whichever answer you give here, the same answer applies to sockets, with the additional twist that a read() on a socket offers you no guarantees whatsoever as to how much you'll read, except that it'll be less than or equal to the size parameter to read(). That's the only warranty you'll get from read().
If the sender called write() twice (and, by the way, sockets also don't guarantee that however much you want to write, that much gets written, write can also return a byte count less than or equal to its size parameter, and it's up to your code to figure out how to deal with it), once writing 76 bytes and the second time with 84, read()ing that (assuming a sufficiently large buffer size) can read any number of bytes between 1 and 160 bytes, on the initial read.
If you wish to implement some formal structure, records of some kind, it is up to you to figure out how to implement it within these constraints. Maybe by sending the size of each record, in bytes, followed by the record itself. Or do whatever you want. Just keep in mind that you have no guarantees, whatsover, how much an individual read() returns. If, for example, you're sending the record count first, as a four byte value. Your initial read() may return one, two, or three bytes. Your code must be prepared to handle any eventuality.

Related

recv() returns always 0

I've a problem with recv() function that I can't explain: it always returns 0. I've a client/server application in which the server simply has to receive a string from the client through the internet (different pc). There are no connectivity problems, and I also tried to send a string from server to client: it worked.
I search in the blog and what I found, recv() socket function returning data with length as 0, non-blocking recv returns 0 when disconnected, Recv returning zero incorrectly, didn't help me to understand.
Here I post the Network class:
Network.h
class Network
{
WSADATA wsaData;
WORD wVersionRequested;
int Port;
unsigned int byteReceived, byteSent;
SOCKET listeningSocket, connectedSocket;
SOCKADDR_IN serverAddr, senderInfo, clientAddr;
int caddrlen;
char buff[DIM];
string buffer;
public:
Network();
~Network();
void Recv();
};
Network.c
void Network::Recv() {
int n = recv(connectedSocket, buff, strlen(buff), 0);
setByteReceived(n);
buffer.assign(buff, n);
cout << "Buffer is: " << buff << endl;
if (byteReceived == 0)
cout << "\tConnection closed" << endl;
else if (byteReceived > 0) {
cout << "\tByte received: " << byteReceived << endl;
cout << getBuffer() << endl;
}
else {
myFormatMessage(WSAGetLastError());
}
}
The behaviour in the end is the following: client and server are connected, the server returns 0 from recv(). I tried also to run both programs on the same machine. Thank you for your help.
You have:
void Network::Recv() {
int n = recv(connectedSocket, buff, strlen(buff), 0);
...
If strlen(buff) returns 0 (because buff contains a null byte at index 0), you will be asking recv() to read 0 bytes, so it will return 0 bytes. You should be using sizeof(buff) instead of strlen(buff).

WinSock C++ Console App Instant Messanger recv doesn't block

I have a question regarding WinSock library.
I'm trying to write simple instant messages program. I wrote it only for 2 clients, and now i would like to improve it, so It can work for many of them, and each client would sent an message with its number and number of the client which will recieve message to the server.
Ive got a problem and I can't figue out, why such simple thing doesnt work:
Code of the client function that sends the messages:
void cClientIO::GetID(SOCKET & socket)
{
u_long iMode = 0;
ioctlsocket(socket, FIONBIO, &iMode);
cout << "Type your ID:" << endl;
cin >> buffer;
send(socket, buffer, sizeof(buffer), 0);
cout << "Type reciever ID" << endl;
cin >> buffer;
//We send buffer to the server;
send(socket,buffer,sizeof(buffer), 0);
}
//Here is the server side:
void cRunServer::GetClientInfo(SOCKET & s){
char buffer[256];
int iResult;
//BLOKUJ pls
u_long iMode = 0;
iResult = ioctlsocket(s, FIONBIO, &iMode);
recv(s, buffer, sizeof(buffer), 0);
cout << "Client number: " << buffer << WSAGetLastError() << endl;
iResult = ioctlsocket(s, FIONBIO, &iMode);
recv(s, buffer, sizeof(buffer), 0);
cout << "Attempts to connect to client ID: " << WSAGetLastError() << endl;
}
I dont know what is going on...
The first recv block my code, but the second one doesnt, and just goes on...
I tried to use GetWSALastError() but it gives me 0 all the time...
Thanks for help in advance.
It doesn't work because the size of the buffers does not match. Client is sending char[2048] and I recv only char[256] and the second call gets the rest of the buffer, and thats why it continues to flow.

Why I am always receiving data on the server side of a socket in C++?

After opening a connection between client and server, I need to handle any write command sent to the server using the command read(); (i.e. when the client write(); the server should read(); right away).
It sounds to be a trivial problem. Firstly, I sent 58 bytes from the client. But, I am always receiving huge amount of data on the server side. Here you could find just the relevant part of code:
int sockfd, newsockfd;//, n0,n1,n2;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
int reuse=1;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
cerr << "ERROR opening socket"<< endl;
if (setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR,&reuse, sizeof(int)) == -1)
cerr << "ERROR on reusing port"<< endl;
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(iport);
serv_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
cerr << "ERROR on binding"<< endl;
cout << "Listening on port: "<< iport<< endl;
listen(sockfd,1);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
cerr << "ERROR on accept" << endl;
while (1) {
size_t msgSize=0;
int n = read(newsockfd,&msgSize,sizeof(size_t));
cout << "Breakpoint " << msgSize<< endl;
// Reading bytes size from socket until 10MB
if ( n> 0 && msgSize< 10485760) {
byte bytes [msgSize];
if (read(newsockfd, bytes, msgSize) > 0) {
char ip [16];
memset (bytes + msgSize, '\0', MSGMAXSIZE - msgSize - 1);
if (read(newsockfd,ip,15) > 0) {
string cIP = (string)ip;
//cout << "Sender Ip: " << cIP << endl;
process p = currentView.getProcess(cIP);
message m(bytes,p);
cout << "*************************" << endl
<< "Message received:" << endl
<< "*****************" << endl;
m.print();
}
}
}
}
This is the result i got:
Listening on port: 4444
Connected to: 127.0.0.1:6666
Breakpoint 58
*************************
Message received:
*****************
Message text: I am trying to send a message
Message size: 58
Message sender: 127.0.0.1
Message stability: 0
**************************************************
Breakpoint 825634866
Breakpoint 808600630
Breakpoint 842478647
Breakpoint 959854903
Breakpoint 926303542
Breakpoint 876032050
Breakpoint 808601142
Breakpoint 892744503
Breakpoint 875971894
Breakpoint 825634866
Breakpoint 1144401970
Breakpoint 859256118
Breakpoint 825635639
Breakpoint 892745526
Breakpoint 775369265
Breakpoint 774909488
Breakpoint 14897
Segmentation fault
And here you could find the relevant part of code from the client side:
while (1)
{
if (!bufferMsg(m)) break;
}
bool bufferMsg(message m) // Sends a message (m) to a process (p)
{
mtx.lock();
if(fifoBuffer.size() < 5)
{
fifoBuffer.push_back(m);
size_t sizeMsg = m.getHeader().sizeMsg;
byte * bytes = m.getBytes();
if (!write(sendsockfd,&sizeMsg,sizeof(size_t)) || !write(sendsockfd,bytes,sizeMsg) || !write(sendsockfd,(char*)m.getHeader().sender.getIp().c_str(),strlen(m.getHeader().sender.getIp().c_str())))
cerr << "ERROR writing to socket"<< endl;
mtx.unlock();
return true;
}
else{
mtx.unlock();
return false;
}
}
Here you could find the header of the message:
typedef struct HeaderType {
size_t sizeMsg;
process sender; // The header.sender process
//view currentView; // the Current view
//iClock C; // reserved for later use
bool stability; // reserved for later use
}HeaderT;
PS: The terms message and process are some classes which I already created but are out of our concern.
Please feel free should you need more clarification or information.
I have the impression you think that client side write should be blocking and waits until the data is eaten up by the server. The OS is free to deliver as many bytes as it likes on a TCP stream.
You have a lot of if if(read(newsockfd, bytes, msgSize) > 0) in your code where you seem to silently assume that the read either fails completely or delivers exactly the amount of data you're waiting for. That doesn't need to be the case.
This:
if ( n> 0 && msgSize< 10485760) {
byte bytes [msgSize];
is dangerous since the byte array (which I assume is a typedef) gets allocated on the stack and I assume no OS on the planet accepts a 10MB local variable. But I might be wrong or even modern compilers start to silently allocate it on the heap. It's the top candidate for your segfault the first time msgSize <10MB. Better do something like:
std::auto_ptr<byte> bytes(new byte[msgSize]);
For your read in of msgSize better do something like:
int n = 0;
int nn = 0;
while((nn=read(newsockfd,((char *)&msgSize)+n,sizeof(size_t)-n)>0
&& n<sizeof(size_t)) {
n+=nn;
}
On the client site you do something like:
write(sendsockfd,(char*)m.getHeader().sender.getIp().c_str(),strlen(m.getHeader().sender.getIp().c_str())
To transfer something like an IP (I assume a string like 88.1.2.250) But on the server side you read it like:
read(newsockfd,ip,15)
which doesn't need to fit each other. That would lead to a frame shift in your read and the next msgSize is bogus. May I assume the the first msgSize you ever read is correct ? Under the assumption that the first read actually delivers sizeof(size-t).
size_t msgSize=0;
int n = 0;
do{
int t=read(newsockfd,((char*)&msgSize) + n, sizeof(size_t) - n);
if(t<0)
continue; //if no data is available (in nonblocking mode, or on timeout)
if(t==0)
break; //connection closed
n+=t; //increase counter n by the amount actually read
} while(n<sizeof(size_t));
cout << "Breakpoint " << msgSize<< endl;
// Reading msgSize bytes from socket until 10MB
if ( n> 0 && msgSize< 10485760) {
byte bytes [msgSize];
n=0;
int t;
while((t=read(newsockfd, bytes + n, msgSize - n)) > 0 //if something was read
&& (n+=t)<msgSize //and the total is below msgSize, we continue reading
|| t<0) //or when there is no data available, we will give it another attempt
{
}
if(t>0){
cout << "successful: " << n << endl;
} else {
cout << "only " << n << " of " << msgSize << "read" << endl;
}
}
Tricky parts explained:
((char*)&msgSize) + n
This casts the pointer to size_t to a pointer to char and + n increments the pointer by n-times the size of the type it points to.
(t=read(newsockfd, bytes + n, msgSize - n)) > 0
An assignment returns the assigned value. It has to be inside brackets, as without brackets the boolean result of the > comparison would be assigned to t.
Sidenote:
You should not send the raw binary representation of an integer value to another computer. The sender might uses a MSB byte order while the recipient could be using LSB. You should use the methods provided to convert from host byte order to network byte order. They are called htonl and ntohl (h:host, to:to, n:network l:long [4 bytes]).

editing tcp client/server to create reverse polish notation calculator server [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am trying to create a reverse polish notation calculator server, I was given the source code for a client and server "see below" and asked to modify it to create the server. i have an idea on how to go about creating the calculator but where do i insert my calculator code in this exisiting server source code. or does it go into the existing client source code.
client source code:
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <iostream>
#include <cstring>
#include <stdlib.h>
#define MAX_LINE 100
#define LINE_ARRAY_SIZE (MAX_LINE+1)
using namespace std;
int main()
{
int socketDescriptor;
unsigned short int serverPort;
struct sockaddr_in serverAddress;
struct hostent *hostInfo;
char buf[LINE_ARRAY_SIZE], c;
cout << "Enter server host name or IP address: ";
cin.get(buf, MAX_LINE, '\n');
// gethostbyname() takes a host name or ip address in "numbers and
// dots" notation, and returns a pointer to a hostent structure,
// which we'll need later. It's not important for us what this
// structure is actually composed of.
hostInfo = gethostbyname(buf);
if (hostInfo == NULL) {
cout << "problem interpreting host: " << buf << "\n";
exit(1);
}
cout << "Enter server port number: ";
cin >> serverPort;
cin.get(c); // dispose of the newline
// Create a socket. "AF_INET" means it will use the IPv4 protocol.
// "SOCK_STREAM" means it will be a reliable connection (i.e., TCP;
// for UDP use SOCK_DGRAM), and I'm not sure what the 0 for the last
// parameter means, but it seems to work.
socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
if (socketDescriptor < 0) {
cerr << "cannot create socket\n";
exit(1);
}
// Connect to server. First we have to set some fields in the
// serverAddress structure. The system will assign me an arbitrary
// local port that is not in use.
serverAddress.sin_family = hostInfo->h_addrtype;
memcpy((char *) &serverAddress.sin_addr.s_addr,
hostInfo->h_addr_list[0], hostInfo->h_length);
serverAddress.sin_port = htons(serverPort);
if (connect(socketDescriptor,
(struct sockaddr *) &serverAddress,
sizeof(serverAddress)) < 0) {
cerr << "cannot connect\n";
exit(1);
}
cout << "\nEnter some lines, and the server will modify them and\n";
cout << "send them back. When you are done, enter a line with\n";
cout << "just a dot, and nothing else.\n";
cout << "If a line is more than " << MAX_LINE << " characters, then\n";
cout << "only the first " << MAX_LINE << " characters will be used.\n\n";
// Prompt the user for input, then read in the input, up to MAX_LINE
// charactars, and then dispose of the rest of the line, including
// the newline character.
cout << "Input: ";
cin.get(buf, MAX_LINE, '\n');
while (cin.get(c) && c != '\n')
;
// Stop when the user inputs a line with just a dot.
while (strcmp(buf, ".")) {
// Send the line to the server.
if (send(socketDescriptor, buf, strlen(buf) + 1, 0) < 0) {
cerr << "cannot send data ";
close(socketDescriptor);
exit(1);
}
// Zero out the buffer.
memset(buf, 0x0, LINE_ARRAY_SIZE);
// Read the modified line back from the server.
if (recv(socketDescriptor, buf, MAX_LINE, 0) < 0) {
cerr << "didn't get response from server?";
close(socketDescriptor);
exit(1);
}
cout << "Modified: " << buf << "\n";
// Prompt the user for input, then read in the input, up to MAX_LINE
// charactars, and then dispose of the rest of the line, including
// the newline character. As above.
cout << "Input: ";
cin.get(buf, MAX_LINE, '\n');
while (cin.get(c) && c != '\n')
;
}
close(socketDescriptor);
return 0;
}
server source code:
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <iostream>
#include <cstring>
#include <stdlib.h>
#define MAX_MSG 100
#define LINE_ARRAY_SIZE (MAX_MSG+1)
using namespace std;
int main()
{
int listenSocket, connectSocket, i;
unsigned short int listenPort;
socklen_t clientAddressLength;
struct sockaddr_in clientAddress, serverAddress;
char line[LINE_ARRAY_SIZE];
cout << "Enter port number to listen on (between 1500 and 65000): ";
cin >> listenPort;
// Create socket for listening for client connection requests.
listenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (listenSocket < 0) {
cerr << "cannot create listen socket";
exit(1);
}
// Bind listen socket to listen port. First set various fields in
// the serverAddress structure, then call bind().
// htonl() and htons() convert long integers and short integers
// (respectively) from host byte order (on x86 this is Least
// Significant Byte first) to network byte order (Most Significant
// Byte first).
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(listenPort);
if (bind(listenSocket,
(struct sockaddr *) &serverAddress,
sizeof(serverAddress)) < 0) {
cerr << "cannot bind socket";
exit(1);
}
// Wait for connections from clients.
// This is a non-blocking call; i.e., it registers this program with
// the system as expecting connections on this socket, and then
// this thread of execution continues on.
listen(listenSocket, 5);
while (1) {
cout << "Waiting for TCP connection on port " << listenPort << " ...\n";
// Accept a connection with a client that is requesting one. The
// accept() call is a blocking call; i.e., this thread of
// execution stops until a connection comes in.
// connectSocket is a new socket that the system provides,
// separate from listenSocket. We *could* accept more
// connections on listenSocket, before connectSocket is closed,
// but this program doesn't do that.
clientAddressLength = sizeof(clientAddress);
connectSocket = accept(listenSocket,
(struct sockaddr *) &clientAddress,
&clientAddressLength);
if (connectSocket < 0) {
cerr << "cannot accept connection ";
exit(1);
}
// Show the IP address of the client.
// inet_ntoa() converts an IP address from binary form to the
// standard "numbers and dots" notation.
cout << " connected to " << inet_ntoa(clientAddress.sin_addr);
// Show the client's port number.
// ntohs() converts a short int from network byte order (which is
// Most Significant Byte first) to host byte order (which on x86,
// for example, is Least Significant Byte first).
cout << ":" << ntohs(clientAddress.sin_port) << "\n";
// Read lines from socket, using recv(), storing them in the line
// array. If no messages are currently available, recv() blocks
// until one arrives.
// First set line to all zeroes, so we'll know where the end of
// the string is.
memset(line, 0x0, LINE_ARRAY_SIZE);
while (recv(connectSocket, line, MAX_MSG, 0) > 0) {
cout << " -- " << line << "\n";
// Convert line to upper case.
for (i = 0; line[i] != '\0'; i++)
line[i] = toupper(line[i]);
// Send converted line back to client.
if (send(connectSocket, line, strlen(line) + 1, 0) < 0)
cerr << "Error: cannot send modified data";
memset(line, 0x0, LINE_ARRAY_SIZE); // set line to all zeroes
}
}
}
while (recv(connectSocket, line, MAX_MSG, 0) > 0) {
//process line, so retrieve numbers, operation
//and call calculator(numbers, operation) and
//convert result to string result
// Send result back to client.
if (send(connectSocket, result, strlen(line) + 1, 0) < 0)
cerr << "Error: cannot send modified data";

raw socket error with sendto: no error code [was: raw socket error with sendto: no such device]

im stuck with sending a raw ethernet frame.
[edit]
I found some errors.
1. It has to be AF_PACKET in the socket call.
2. AF_PACKET doesnt have an option SOCK_PACKET, but SOCK_DGRAM and SOCK_RAW
With SOCK_DGRAM wireshark captures a malformed LLC packet.
But with SOCK_RAW no error message and no captured packet.
i dont find whats really going wrong.
[/edit]
the code:
if ((ethernet_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1)
cout << "Ethernet Socket: "<< strerror(errno) << endl;
struct sockaddr_ll socket_address;
socket_address.sll_family = PF_PACKET;
socket_address.sll_protocol = htons(ETH_P_IP);
socket_address.sll_ifindex=if_nametoindex("eth0");
socket_address.sll_hatype = 1; // ARPHRD_ETHER
socket_address.sll_pkttype = PACKET_OTHERHOST;
socket_address.sll_halen = ETH_ALEN;
memcpy(socket_address.sll_addr,dest_mac_addr,ETH_ALEN);
int send_result = 0;
char *opt=(char*)malloc(4*sizeof(char));
strcpy(opt,"eth0");
if(setsockopt(ethernet_socket, SOL_SOCKET, SO_BINDTODEVICE, opt, 4)==-1)
cout << "Could not bind socket to device: " << strerror(errno) << endl;
if ((send_result
= sendto(ethernet_socket, &buffer, sizeof(buffer), 0,
(struct sockaddr*)&socket_address, sizeof(socket_address)))==-1){
cout << "sendto error: "<< strerror(errno) << endl;
return send_result;
}
regards
Ck
I found the solution how this works.
i took a look at the source code of the Linux program PackEth.
the following code works for me.
if ((ethernet_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1)
cout << "Ethernet Socket: "<< strerror(errno) << endl; //errorhandling
memset(&ifr, 0, sizeof(ifr));
strncpy (ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1);
ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
if (ioctl(ethernet_socket, SIOCGIFINDEX, &ifr) == -1) {
cout << "No such interface:"<< strerror(errno) << endl;
close(ethernet_socket);
}
ioctl(ethernet_socket, SIOCGIFFLAGS, &ifr);
if ( (ifr.ifr_flags & 0x1) == 0) {
cout << "Interface is down: "<< strerror(errno) << endl;
close(ethernet_socket);
}
ioctl(ethernet_socket, SIOCGIFINDEX, &ifr);
memset(&socket_address, 0, sizeof (socket_address));
socket_address.sll_family = AF_PACKET;
socket_address.sll_ifindex = ifr.ifr_ifindex;
socket_address.sll_protocol = htons(ETH_P_ALL);
if ((raw_send = sendto(ethernet_socket, buffer, size_payload+14,0,(struct sockaddr*)
&socket_address, sizeof(socket_address)))==-1){
cout << "sendto error: "<< strerror(errno) << endl;
return raw_send;
}
$ man 7 packet
"SOCK_RAW packets are passed to and from the device driver without any changes in the packet data. When receiving a packet, the address is still parsed and passed in a standard sockaddr_ll address structure. When transmitting a packet, the user supplied buffer should contain the physical layer header. That packet is then queued unmodified to the network driver of the interface defined by the destination address. Some device drivers always add other headers.
SOCK_DGRAM operates on a slightly higher level. The physical header is removed before the packet is passed to the user. Packets sent through a SOCK_DGRAM packet socket get a suitable physical layer header based on the information in the sockaddr_ll destination address before they are queued."