I'm beginner to Networking. We have sender and receiver application. I have captured the packets sent by sender to receiver using WinDump.
I'm writing a python sender application which will fuzz the packets sent by sender to receiver.
I just want to confirm, can I directly put the packet data obtained using WinDump to socket send() method.
Say, "arp who-has host1 tell host2" is the packet obtained by WinDump
Can I write,
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(arp who-has host1 tell host2)
In general pyhton network programming you can not pass as the arguments using send method.you just only pass the string as arguments as variable.
Basically we are using the send() and sendall() method to transmits the TCP messages.
I have mentioned the below desciption for both the method.
socket send() method :
The socket's send() method is not guaranteed to send all of the data you pass it. Instead, it returns the number of bytes that were actually sent and expects your application to handle retransmission of the unsent portion
from socket import socket
sock = socket()
sock.connect(('1.2.3.4', 1234))
sock.send('My Name is Dasadiya Chaitanya !!!\n'')
sock.close()
socket sendall() method :
which is same work as the send() method but python provides a convenience method called sendall() that makes sure all of your data is sent before returning and also provide the guarantee to send all the data to the receiver.
from socket import socket
sock = socket()
sock.connect(('1.2.3.4', 1234))
sock.sendall('My Name is Dasadiya Chaitanya !!!\n')
sock.close()
I hope this should helpful for you :)
Related
Let's say i created my own packet called myPacket. Is there a way i can send it using socket.sendTo()?
I know socket.sendTo() takes in an INET packet so is there a way to convert myPacket into an INET packet?
The module that is going to receive the packet is Radio. I checked Radio's functions and they take in an inet packet so what can i do about it?
Signal *Radio::createSignal(Packet *packet) const
{
encapsulate(packet);
if (sendRawBytes) {
auto rawPacket = new Packet(packet->getName(), packet->peekAllAsBytes());
rawPacket->copyTags(*packet);
delete packet;
packet = rawPacket;
}
Signal *signal = check_and_cast<Signal *>(medium->transmitPacket(this, packet));
ASSERT(signal->getDuration() != 0);
return signal;
}
Sending messages using sockets needs a socket on the other side. If you have a socket at the other side so go ahead and send your message using a socket.
Basically, messages sent by using the cSimpleModule basic member function send(). This method is used to send messages to other modules through gates. One can also use the scheduleAt() to send a message at specific point in time.
If you use a higher level application such as http or tcp applications, so you are most probably going to use sockets. Sockets also use send() and scheduleAt() to send messages through gates.
You need to do 4 steps:
Define your own .msg class and extend some of the inet predefined classes. See inet/applications/base/ApplicationPacket.msg as an example.
Define your communication protocol aka inet socket object to pass the messages. Look at this guide. Don't forget to pass destination address and port, normally they are defined as .NED parameters and injected through the omnetpp.ini file.
Then you need to write a method, which builds your packet and sends it to the destination address. Take a look at the method UdpBasicApp::sendPacket() at inet/applications/udpapp/UdpBasicApp.cc as an example.
At receiver side I usually have a bunch of processing methods switched in handleMessage method or similar one to catch all possible messages my receiver can receive and process. All such methods take cMessage* msg as an argument and then at the beginning:
Packet* packet = check_and_cast<Packet*>(msg);
if (!packet) {
return;
}
const auto& payload = packet->peekAtFront<YourOwnPacketClass>();
// work with you message body...
Whenever I send a message from my client to the server (or vice versa), I have to wait until I've sent a message from the other side for it to register.
server.py
from socket import *
host = '127.0.0.1'
port = 80
s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
while True:
message = raw_input("Send message: ")
s.send(message)
print s.recv(1024)
client.py
from socket import *
host = '127.0.0.1'
port = 80
s = socket(AF_INET, SOCK_STREAM)
s.bind((host, port))
s.listen(5)
c,addr = s.accept()
while True:
message = raw_input("Send message: ")
c.send(message)
print c.recv(1024)
Example:
server sends message
nothing happens on client side
client sends message
both server and client receive their messages
this will happen over and over
Well, it's obvious that you have to wait for "the other side" because you have raw_input calls sitting in your code that are waiting for the user to type something...
That said, you're also recv'ing 1024 bytes but sending much less, probably. Thus the recv() will usually hang until it has enough data (but not always, in which case it returns less). Remember that with lowlevel socket communication you have to properly take care of message sizes/boundaries yourself!
You can agree on a termination byte such as "\n" that signifies the boundary between messages, or another strategy is to prepend every message by a few bytes that signify the size of the message following it. You then recv() exactly that amount. Or just send a fixed amount of data for every message.
What remains is that you still have to deal with the fact that send() and recv() sometimes don't send or receive everything: they have a return value that is important. Using sendall, and recv with the MSG_WAITALL flag can take care of most issues, but there's no guarantee.
Read this https://docs.python.org/3/howto/sockets.html#using-a-socket for starters.
I'm in the process of writing a project for college involving writing a chat client and server using POSIX sockets and C++.
The clients are supposed to converse with each other using P2P, such as each client has his own open UDP socket through which he sends and recieves messages from/to other clients.
My problem is 2-fold:
My UDPSocket class constructor seems to be ignoring the port number completely, binding to port 65535 regardless of the parameter.
The port is binding to IP 255.255.255.255 rather than my own IP (10.0.0.3), or at least that's what i get when I call getpeername.
To the best of my knowledge passing INADDR_ANY should bind to my local address, and passing port number 0 should make the OS choose a free port, what am I doing wrong?
This is the constructor of my UDPSocket class:
UDPSocket::UDPSocket(int port){
socket_fd = socket (AF_INET, SOCK_DGRAM, 0);
// clear the s_in struct
bzero((char *) &in, sizeof(in)); /* They say you must do this */
//sets the sin address
in.sin_family = (short)AF_INET;
in.sin_addr.s_addr = htonl(INADDR_ANY); /* WILDCARD */
in.sin_port = htons((u_short)port);
fsize = sizeof(from);
//bind the socket on the specified address
if(bind(socket_fd, (struct sockaddr *)&in, sizeof(in))<0){
perror ("Error naming channel");
}
}
This is the initialization:
m_Socket = new UDPSocket(0);
And this is the method I use to retrieve the binded address: (UDPSocket inherits Socket)
std::string Socket::GetSocketAddress()
{
struct sockaddr_in addr;
int len = sizeof(addr);
getpeername(socket_fd, (struct sockaddr*)&addr, (socklen_t*)&len);
char ipAddressBuffer[50];
memset(ipAddressBuffer, 0, sizeof(ipAddressBuffer));
sprintf(ipAddressBuffer, "%s:%d", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
return ipAddressBuffer;
}
Any help would be greatly appreciated,
Avi.
You're using getpeername , which gives you the remote address of a connected socket. If you check the return value of getpeername(), it should indicate failure.
You need to use getsockname() instead of getpeername() to get the address of your local socket
You need to check that getsockname() succeeds.
Note that your socket is bound to the special 0.0.0.0 address, which means "all local interfaces", so that's what getsockname() will also return.
Answering the more general question "How to set up peer-to-peer communications with UDP":
With UDP sockets, while you can use connect, you generally don't want to, as that restricts you to a single peer per socket. Instead, you want to use a single unconnected UDP socket in each peer with the sendto and recvfrom system calls to send and receive packets with a different address for each packet.
The sendto function takes a packet and a peer address to send it to, while the recvfrom function returns a packet and the peer address it came from. With a single socket, there's no need to multiplexing with select or poll -- you just call recvfrom to get the next packet from any source. When you get a packet, you also get the peer address to send packets (back) to.
On startup, your peer will create a single socket and bind it to INADDR_ANY (allowing it to receive packets on any interface or broadcast address on the machine) and either the specific port assigned to you program or port 0 (allowing the OS to pick any unused port). In the latter case, you'll need to use getsockname to get the port and report it to the user. Once the socket is set up, the peer program can sendto any peer it knows about, or recvfrom any peer at all (including those it does not yet know about).
So the only tricky part is bootstrapping -- getting the first packet(s) flowing so that peers can recieve them and figure out their peer addresses to talk to. One method is specifying peer addresses on the command line when you start each peer. You'll start the first one with no arguments (as it has no peers -- yet). It will just recvfrom (after socket setup) to get packets from peers. Start the second with the address of the first as an argument. It sends a packet (or several) to the first peer, which will then know about the new peer as soon as it gets the first packet. Now start a third client with the addresses of the first two on the command line...
I am very new to networking and have an issue with sending messages during a while loop.
To my knowledge I should do something along the lines of this:
Create Socket()
Connect()
While
Do logic
Send()
End while
Close Socket()
However it sends once and returns -1 there after.
The code will only work when I create the socket in the loop.
While
Create Socket()
Connect()
Do logic
Send()
Close Socket()
End while
Here is a section of the code I am using but doesn't work:
//init winsock
WSAStartup(MAKEWORD(2, 0), &wsaData);
//open socket
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
//connect
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(ipaddress);
serveraddr.sin_port = htons((unsigned short) port);
connect(sock, (struct sockaddr *) &serveraddr, sizeof(serveraddr));
while(true) {
if (send(sock, request.c_str(), request.length(), 0)< 0 /*!= request.length()*/) {
OutputDebugString(TEXT("Failed to send."));
} else {
OutputDebugString(TEXT("Activity sent."));
}
Sleep(30000);
}
//disconnect
closesocket(sock);
//cleanup
WSACleanup();
The function CheckForLastError() returns:10053
WSAECONNABORTED
Software caused connection abort.
An established connection was aborted by the software in your host computer, possibly due to a data transmission time-out or protocol error
Thanks
I have been looking for a solution to this problem too. I am having the same problem with my server. When trying to send a response from inside the loop, the client seems never to receive it.
As I understand the problem, according to user207421's suggestions, when you establish a connection between a client and a server, the protocol should have enough information to let the client know when the server has finished sending the response. If you see this example, you have a minimum HTTP server that responds to requests. In this case, you can use a browser or an application like Postman. And if you see the response message, you will see a header called Connection. Setting its value to close tells the client which one is the last message from the server for that request. The message is being sent, but the client keeps waiting, maybe because there is no closing element the client can recognize. I was also missing the Content-Length header. My HTTP response message was wrong, and the client was lost.
This diagram shows what needs to be outside the loop and what needs to be inside.
To understand how and why your program fails,you have to understand the functions you use.
Some of them are blocking functions and some are them not. Some of them need previous calles of other functions and some of them don't.
Now from what i understand we are talking about a client here,not a server.
The client has only non blocking functions in this case. That means that whenever you call a function,it will be executed without waiting.
So send() will send data the second it is called and the stream will go on to the next line of code.
If the information to be sent was not yet ready...you will have a problem,since nothing will be sent.
To solve it you could use some sort of a delay. The problem with delays is that they are Blocking functions meaning your stream will stop once it hits the delay. To solve it you can create a thread and lock it untill the information is ready to be sent.
But that would do the job for one send(). You will send the info and thats that.
If you want to hold the communication and send repeatedly info,you will need to create a while loop. once you have a while loop you dont have to worry about anything. That is because you can verify that the information is ready with a stream control and you can use send over and over again before terminating the connection.
Now the question is what is happening on the server side of things?
"ipaddress" should hold the ip of the server. The server might reject your request to connect.Or worst he might accept your request but he is listening with diffrent settings in relation to your client.Meaning that maybe the server is not reciving (does not have recv() function)information and you are trying to send info... that might resault in errors/crashes and what not.
I'm trying to write an IOCP server. Basically, I have it accepting new connections. For the purpose of my testing, I'm running and connecting to 127.0.0.1.
I create the pseudo socket prior to calling AcceptEx(). Once a connection is accepted, the new pseudo socket is used for communication. This new socket is associated with an io completion port [CreateIoCompletionPort], I then assign it a few options, [SO_EXCLUSIVEADDRUSE] and [SO_CONDITIONAL_ACCEPT], and then I call WSARecv() to accept incoming data.
The problem is that once my remote connection connects to the server, it sends data, but that data is never received. I'm wondering if someone could offer some ideas as to why it's not receiving data? Perhaps my logic is flawed? I stepped through my code several times. no errors are recorded.
EDIT: Fixed the wording. I create the socket before AcceptEx() call.
Basic logic in my code:
// Create socket, associate with IOCP
WSASocket(af, type, proto, lpProtoInfo, g, dwFlags);
HANDLE hIOCP = GetPool()->GetQueueHandle();
CreateIoCompletionPort(hSource, hIOCP, 0, 0) != NULL;
// Server bind and listen
bind(m_shSocket, pAddr, nAddrLen);
listen(m_shSocket, nBacklog);
// Creation of the pseudo socket
SOCKET s = ::WSASocket(m_iSocketAf, m_iSocketType, m_iSocketProto, m_pWpi, m_SocketGroup, m_dwSocketFlags);
DWORD dwBytes;
BOOL bRet = m_fnAcceptEx(m_shSocket, s, chOutput, 0, sizeof(SOCKADDR_STORAGE) + 16, sizeof(SOCKADDR_STORAGE) + 16, &dwBytes, m_pcbAccept);
// ... New Connection comes in, it's accepted ...
// Associate new pseudo socket with IOCP
HANDLE hNewIOCP = GetPool()->GetQueueHandle();
CreateIoCompletionPort((HANDLE) s, hNewIOCP , 0, 0) != NULL;
// ... Remote socket sends ...
// ... Remote socket and Pseudo socket call WSARecv ...
// ... Pseudo socket does not receive ...
NOTE: I tried sending from the pseudo socket to the remote socket, same problem as sending data in the reverse way.
You need to post some code but your description doesn't make sense. That's NOT how AcceptEx() based servers operate.
With an AcceptEx() based server you create your accepted socket before you post the AcceptEx(). You then post the AcceptEx() with the listening socket and the new socket and a buffer which allows you to receive the remote address and, optionally, data.
So if you are describing your code in your original question then your code is wrong or you're not using AcceptEx(). I'm currently ignoring the 'few options' that you throw into the mix as they simply further confuse things at present without any code to analyse.
You might be interested in downloading my free IOCP based server framework, which includes working AcceptEx() and traditional Accept() based server code. You can get it from here: http://www.serverframework.com/products---the-free-framework.html
Are you calling GetQueuedCompletionStatus to get the data?
In case you are not doing this just to learn for yourself, I would also recommend that you use boost::asio - an excellent library that allows you to let someone else do the tedious code for handling the io completion ports.
I figured it out. I'm an idiot. I was sending zero bytes.