void run(void) { Frame* frame = NULL; IOMultiplexing iom; m_socket.addToPoll(iom); while (!isStopping()) { if (!iom.poll(1.0)) continue; int rv = m_socket.read((char*)m_buffer, m_buffer_capacity); if (rv == c_header_size) { m_count = 0; frame = dequeueClean(); if (frame == NULL) { DUNE_ERR("GVSP", "buffer overrun"); break; } frame->setTimeStamp(); } else if (rv == c_footer_size) { enqueueDirty(frame); frame = NULL; } else { if (frame != NULL) { uint16_t packet_number = 0; ByteCopy::fromBE(packet_number, m_buffer + 6); m_count += frame->writePacket(packet_number, m_buffer + 8, rv - 8); } else { DUNE_ERR("GVSP", "null frame"); } } } }
/** Submit an SMS for delivery to an IMSI. */ int sendsimple(int argc, char** argv, ostream& os) { if (argc<4) return BAD_NUM_ARGS; char *IMSI = argv[1]; char *srcAddr = argv[2]; string rest = ""; for (int i=3; i<argc; i++) rest = rest + argv[i] + " "; const char *txtBuf = rest.c_str(); if (!isIMSI(IMSI)) { os << "Invalid IMSI. Enter 15 digits only."; return BAD_VALUE; } static UDPSocket sock(0,"127.0.0.1",gConfig.getNum("SIP.Local.Port")); static const char form[] = "MESSAGE sip:IMSI%[email protected] SIP/2.0\n" "Via: SIP/2.0/TCP 127.0.0.1;branch=%x\n" "Max-Forwards: 2\n" "From: %s <sip:%[email protected]:%d>;tag=%d\n" "To: sip:IMSI%[email protected]\n" "Call-ID: %[email protected]:%d\n" "CSeq: 1 MESSAGE\n" "Content-Type: text/plain\nContent-Length: %u\n" "\n%s\n"; static char buffer[1500]; snprintf(buffer,1499,form, IMSI, (unsigned)random(), srcAddr,srcAddr,sock.port(),(unsigned)random(), IMSI, (unsigned)random(),sock.port(), strlen(txtBuf), txtBuf); sock.write(buffer); os << "message submitted for delivery" << endl; #if 0 int numRead = sock.read(buffer,10000); if (numRead>=0) { buffer[numRead]='\0'; os << "response: " << buffer << endl; } else { os << "timed out waiting for response"; } #endif return SUCCESS; }
void run(void) { Frame* frame = NULL; while (!isStopping()) { if (!Poll::poll(m_socket, 1.0)) continue; size_t rv = m_socket.read(m_buffer, m_buffer_capacity); if (rv == c_header_size) { m_count = 0; frame = dequeueClean(); if (frame == NULL) { m_task->err(DTR("buffer overrun")); break; } frame->setTimeStamp(); } else if (rv == c_footer_size) { enqueueDirty(frame); frame = NULL; } else { if (frame != NULL) { uint16_t packet_number = 0; ByteCopy::fromBE(packet_number, m_buffer + 6); m_count += frame->writePacket(packet_number, m_buffer + 8, rv - 8); } else { m_task->err(DTR("null frame")); } } } }
TEST(Network, UDPSocket) { UDPWriteDesc writeDesc; writeDesc.port = 5005; writeDesc.address = "localhost"; UDPSocket writeSocket; ASSERT_TRUE(writeSocket.connect(writeDesc)); std::string str = "Hello World"; UDPReadDesc readDesc; readDesc.port = 5005; char buffer[1024]; UDPSocket socket; ASSERT_TRUE(socket.connect(readDesc)); ASSERT_EQ(writeSocket.write(str.c_str(), str.length()), str.length()); ASSERT_EQ(socket.read(buffer, 1024), str.length()); ASSERT_STREQ(str.c_str(), buffer); AM_LOG_SUCCESS("%s", buffer); }
int main() { //create tcp socket and establish a connection TCPServerSocket tcpServerSocket; int ret = tcpServerSocket.initialize(); ASSERT(ret == 0); int serverUdpPort = tcpServerSocket.negotiate(); ASSERT(serverUdpPort > 1024); tcpServerSocket.close(); //open a udp socket and listen for str UDPSocket udpSocket; ret = udpSocket.open(serverUdpPort); ASSERT(ret == 0); LOG("Server opened UDP Port %i\n", serverUdpPort); char buf[1024]; unsigned long remoteIp; int remotePort; //read, reverse string and send it back to client int readBytes = udpSocket.read(buf, 1024, remoteIp, remotePort); buf[readBytes] = '\0'; ASSERT(readBytes > 0); LOG("Server Received: %s\n", buf); //Reverse the string and write to the buffer again str_reverse(buf); int writeBytes = udpSocket.write(remoteIp, remotePort, (const char *) buf, readBytes); ASSERT(writeBytes > 0); LOG("Server sent: %s\n", buf); udpSocket.close(); return 0; }
int main(int argc, char* argv[]) { //parse args if (argc != 5) { std::cout << "This program requires 4 arguments in the following format!" << std::endl; std::cout << "sender <host address of emulator> <udp port number of emulator in FWD direction>" << "\n" << "<udp port number of sender to receive acks> <fileName>" << std::endl; std::cout << "Example: sender 192.168.89.78 49998 11234 test.txt" << std::endl; return 1; } const char* ipAddr = argv[1]; if (0 == strcmp(ipAddr, "localhost")) { ipAddr = "127.0.0.1"; } unsigned long remoteIp = inet_addr(ipAddr); int remotePort = atoi(argv[2]); int senderPort = atoi(argv[3]); const char* fileName = argv[4]; int totalPackets = 0; int totalBytes = 0; int sentPackets = 0; int sentBytes = 0; int seqNum = 0; signal(SIGALRM, signal_alarm_handler); bool timer_on = false; list<Packet *> packetsToSend; list<Packet *> packetsSent; //Open the file and prepare the packets for transmission ifstream transferFile(fileName); ofstream seqLog(seqFile); ofstream ackLog(ackFile); if (!(seqLog.is_open() && ackLog.is_open())) { return 1; } if (transferFile.is_open()) { char buffer[Packet::MAX_DATA_LENGTH]; while(false == transferFile.eof()) { transferFile.read(buffer, Packet::MAX_DATA_LENGTH); Packet* packet = Packet::createPacket(seqNum, transferFile.gcount(), buffer); packetsToSend.insert(packetsToSend.end(), packet); LOG("Inserted packet %i in the queue\n", totalPackets); seqNum++; seqNum %= Packet::MAX_SEQ_NUMBER; totalPackets++; totalBytes += packet->getLength(); } } else { LOG("The input file was not found..\n"); return 1; } transferFile.close(); //Add EOT packet Packet *eotPacket = Packet::createEOT(seqNum); packetsToSend.insert(packetsToSend.end(), eotPacket); totalPackets++; LOG("Packets ready for transmission: %i\n", totalPackets); LOG("Total data to be sent: %i\n", totalBytes); //open a udp socket and listen for str UDPSocket udpSocket; int ret = udpSocket.open(senderPort); ASSERT(ret == 0); LOG("Sender is transmitting & receiving on UDP Port %i\n", senderPort); /** * Core Logic * The sender can be in three states * 1. SEND_DATA : Sends a packet as long as data is available and window size is permitted * 2. RECV_ACK : Receives an acknowledgement for a previously sent data * 3. RESEND_DATA: If an ACK is not received for a previously sent data within timer, resend the data */ while ((packetsToSend.size() > 0) || (packetsSent.size() > 0)) { if (udpSocket.hasData()) { g_state = SENDER_RECV_ACK; } switch(g_state) { /** * Within the WINDOW_SIZE, if data is available, send it. * Remove it from packetsToSend, and add it to packetsSent * If timer is off, turn it on. */ case SENDER_SEND_DATA: { if (packetsSent.size() < WINDOW_SIZE && packetsToSend.size() > 0) { list<Packet *>::iterator itr = packetsToSend.begin(); Packet *packet = (*itr); char *packetData = packet->getUDPData(); udpSocket.write(remoteIp, remotePort, packetData, packet->getUDPSize()); sentPackets++; sentBytes += packet->getLength(); seqLog << packet->getSeqNum() << endl; LOG("Sent packet seqnum %i, packet number %i\n", packet->getSeqNum(), sentPackets); LOG("Sent bytes: %i\n", sentBytes); if (false == timer_on) { alarm(TIMER_SECS); timer_on = true; } free(packetData); packetsToSend.remove(packet); packetsSent.insert(packetsSent.end(), packet); } } break; /** * 1. RECV Packet. * 2. Check if the ack number belongs to any packets in packetsSent. * 3. If yes, delete all packets upto and before. * 4. If not, discard packet * 5. If any packets are sent and not recieved ack, start timer again. */ case SENDER_RECV_ACK: { char buffer[Packet::MAX_PACKET_LENGTH]; unsigned long ip; int port; int length = Packet::MAX_PACKET_LENGTH; udpSocket.read(buffer, length, ip, port); Packet *packet = Packet::parseUDPData(buffer); int seqNum = packet->getSeqNum(); ackLog << seqNum << endl; //since it is cumulative keep deleting until seq num is found on packetsSent list<Packet *>::iterator itr = packetsSent.begin(); while (itr != packetsSent.end() && comparePacket((*itr)->getSeqNum(), seqNum) <= 0) { //less than or equal Packet *sentPacket = (*itr); packetsSent.remove(sentPacket); itr = packetsSent.begin(); delete(sentPacket); } delete(packet); if (packetsSent.size() > 0) { alarm(TIMER_SECS); } g_state = SENDER_SEND_DATA; } break; /** * 1. Resend data if timeout. * 2. Send all packets in packetsToSend */ case SENDER_RESEND_DATA: { for (list<Packet *>::iterator itr = packetsSent.begin(); itr != packetsSent.end(); ++itr) { Packet *packet = (*itr); char *packetData = packet->getUDPData(); udpSocket.write(remoteIp, remotePort, packetData, packet->getUDPSize()); seqLog << packet->getSeqNum() << endl; LOG("Resent packet seqnum %i\n", packet->getSeqNum()); if (false == timer_on) { alarm(TIMER_SECS); timer_on = true; } free(packetData); } } break; default: { ASSERT(0); //invalid state } } } LOG("End of Transmission. Exiting \n"); udpSocket.close(); seqLog.close(); ackLog.close(); ASSERT(totalBytes == sentBytes); ASSERT(totalPackets == sentPackets); return 0; }
int main(int argc, char *argv[]) { //parse args if (argc != 5) { std::cout << "This program requires 4 arguments in the following format!" << std::endl; std::cout << "receiver <ipAddress of network emulator> <udp port of emulator to receive ACKs from receiver>" << endl << "<udp port number used by receiver to receive data> <fileName>" << std::endl; std::cout << "Example: receiver 192.123.45.87 49999 11235 recv_test.txt" << std::endl; return 1; } const char* ipAddr = argv[1]; if (0 == strcmp(ipAddr, "localhost")) { ipAddr = "127.0.0.1"; } unsigned long remoteIp = inet_addr(ipAddr); int remotePort = atoi(argv[2]); int receiverPort = atoi(argv[3]); const char *recvFile = argv[4]; list<Packet *> packetsReceived; unsigned int totalBytes = 0; unsigned int expectingSeqNum = 0; bool firstPacketReceived = false; //create a udp socket UDPSocket udpSocket; udpSocket.open(receiverPort); LOG("Receiver opened UDP port at %i\n", receiverPort); ofstream arrivalLog(arrivalFile); if (!arrivalLog.is_open()) { LOG("Arrival log file cannot be opened\n"); return 1; } /** * RECV Packet. * If the sequence number is expected, add it to packets list. Send Ack. * If not discard and send previous ack. */ while (true) { char buf[Packet::MAX_PACKET_LENGTH]; unsigned long ip; int port; udpSocket.read(buf, Packet::MAX_PACKET_LENGTH, ip, port); Packet *packet = Packet::parseUDPData(buf); arrivalLog << packet->getSeqNum() << endl; LOG("Received packet %i, length %i\n", packet->getSeqNum(), packet->getLength()); if ((unsigned int) packet->getSeqNum() == expectingSeqNum) { if (packet->getType() == 1) { //data packet sendAckPacket(udpSocket, expectingSeqNum, remoteIp, remotePort); totalBytes += packet->getLength(); LOG("Received %i bytes\n", totalBytes); expectingSeqNum++; expectingSeqNum %= Packet::MAX_SEQ_NUMBER; packetsReceived.insert(packetsReceived.end(), packet); LOG("Total packets received %i\n", (unsigned int) packetsReceived.size()); if (false == firstPacketReceived) { firstPacketReceived = true; } } else if (packet->getType() == 2) { //eot packet LOG("EOT Packet received.. \n"); sendEotPacket(udpSocket, expectingSeqNum, remoteIp, remotePort); break; } } else { if (true == firstPacketReceived) { int previousSeqNum = expectingSeqNum - 1; previousSeqNum = (previousSeqNum + Packet::MAX_SEQ_NUMBER) % Packet::MAX_SEQ_NUMBER; sendAckPacket(udpSocket, previousSeqNum, remoteIp, remotePort); } delete(packet); } } udpSocket.close(); LOG("Received %u packets \n", (unsigned int) packetsReceived.size()); //Write to a file. ofstream transferFile(recvFile); if (transferFile.is_open()) { for (list<Packet *>::iterator itr = packetsReceived.begin(); itr != packetsReceived.end(); ++itr) { Packet *packet = (*itr); transferFile.write(packet->getData(), packet->getLength()); delete(packet); } } LOG("Finished writing %u bytes to the file\n", totalBytes); transferFile.close(); arrivalLog.close(); return 0; }