int transmit(int* arg) { char buffer[BUFFER_SIZE]; int length; int i; minithread_t receiver1; minithread_t receiver2; miniport_t write_port1; miniport_t write_port2; network_address_t my_address; network_get_my_address(&my_address); port1 = miniport_create_unbound(0); port2 = miniport_create_unbound(1); write_port1 = miniport_create_bound(my_address, 0); write_port2 = miniport_create_bound(my_address, 1); receiver1 = minithread_fork(receive1, NULL); receiver2 = minithread_fork(receive2, NULL); for (i=0; i<MAX_COUNT; i++) { printf("Sending packet %d to receiver 1.\n", i+1); sprintf(buffer, "Count for receiver 1 is %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port1, write_port1, buffer, length); minithread_yield(); printf("Sending packet %d to receiver 2.\n", i+1); sprintf(buffer, "Count for receiver 2 is %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port2, write_port2, buffer, length); } return 0; }
int transmit1(int* arg) { char buffer[BUFFER_SIZE]; int length; int i; network_address_t addr; miniport_t port; miniport_t dest; AbortOnCondition(network_translate_hostname(hostname, addr) < 0, "Could not resolve hostname, exiting."); port = miniport_create_unbound(0); dest = miniport_create_bound(addr, 1); for (i=MAX_COUNT/2; i<MAX_COUNT; i++) { printf("Sending packet %d.\n", i+1); sprintf(buffer, "Count is %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port, dest, buffer, length); minithread_yield(); } return 0; }
int transmit1(int* arg) { char buffer[BUFFER_SIZE]; int length; int i; minithread_t transmitter2; minithread_t receiver; miniport_t write_port; network_get_my_address(&my_address); port = miniport_create_unbound(0); write_port = miniport_create_bound(my_address, 0); transmitter2 = minithread_fork(transmit2, NULL); receiver = minithread_fork(receive, NULL); for (i=0; i<MAX_COUNT; i++) { printf("Sending packet %d from sender 1.\n", i+1); sprintf(buffer, "Count from sender 1 is %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port, write_port, buffer, length); minithread_yield(); } return 0; }
int send(int* arg) { char buffer[BUFFER_SIZE]; int length = BUFFER_SIZE; int i; network_address_t addr; miniport_t *dest; miniport_t *equal_test; network_get_my_address(addr); equal_test = miniport_create_unbound(100); if (port != equal_test) { fprintf(stderr, "miniport_create unbound is duplicating ports \n"); exit(0); } dest = miniport_create_bound(addr, 100); for (i=0; i<MSG_PER_PORT; i++) { messageCount++; sprintf(buffer, "Received packet number %d \n", messageCount); length = strlen(buffer) + 1; minimsg_send(port, dest, buffer, length); fprintf(stderr, "sending %d \n", messageCount); } miniport_destroy(dest); return 0; }
int transmit_first(int* arg) { char buffer[BUFFER_SIZE]; int length = BUFFER_SIZE; int i; network_address_t addr; miniport_t port; miniport_t dest; miniport_t from; AbortOnCondition(network_translate_hostname(hostname, addr) < 0, "Could not resolve hostname, exiting."); port = miniport_create_unbound(0); dest = miniport_create_bound(addr, 1); for (i=0; i<MAX_COUNT; i++) { printf("Sending packet %d.\n", i+1); sprintf(buffer, "Received packet %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port, dest, buffer, length); length = BUFFER_SIZE; minimsg_receive(port, &from, buffer, &length); printf("%s", buffer); miniport_destroy(from); } return 0; }
/* Receives a message through a locally unbound port. Threads that call this function are * blocked until a message arrives. Upon arrival of each message, the function must create * a new bound port that targets the sender's address and listening port, so that use of * this created bound port results in replying directly back to the sender. It is the * responsibility of this function to strip off and parse the header before returning the * data payload and data length via the respective msg and len parameter. The return value * of this function is the number of data payload bytes received not inclusive of the header. */ int minimsg_receive(miniport_t local_unbound_port, miniport_t* new_local_bound_port, minimsg_t msg, int *len) { network_interrupt_arg_t* pkt; mini_header_t pkt_header; char protocol; network_address_t src_addr; unsigned short src_port; network_address_t dst_addr; int i; char* buff; if (local_unbound_port == NULL || local_unbound_port->p_type != UNBOUND_PORT || local_unbound_port->p_num >= BOUND_PORT_START || miniport_array[local_unbound_port->p_num] != local_unbound_port){ return -1; } //block until packet arrives semaphore_P(local_unbound_port->u.unbound.port_pkt_available_sem); semaphore_P(local_unbound_port->u.unbound.q_lock); if( queue_dequeue(local_unbound_port->u.unbound.port_pkt_q, (void**)&pkt)){ return -1; } semaphore_V(local_unbound_port->u.unbound.q_lock); pkt_header = (mini_header_t)(&pkt->buffer); protocol = pkt_header->protocol; unpack_address(pkt_header->source_address, src_addr); src_port = unpack_unsigned_short(pkt_header->source_port); unpack_address(pkt_header->destination_address, dst_addr); if (protocol != PROTOCOL_MINIDATAGRAM && protocol != PROTOCOL_MINISTREAM){ return -1; } if (protocol == PROTOCOL_MINISTREAM){ return 0; //currently unsupported } else { //UDP if ( pkt->size < sizeof(struct mini_header)){ return -1; } *len = pkt->size-sizeof(struct mini_header) > *len? *len : pkt->size-sizeof(struct mini_header); *new_local_bound_port = miniport_create_bound(pkt->sender, src_port); //copy payload buff = (char*)&(pkt->buffer); buff += sizeof(struct mini_header); for (i = 0; i < *len; i++){ msg[i] = *buff; buff++; } free(pkt); return *len; } }
/* Receives a message through a locally unbound port. Threads that call this function are * blocked until a message arrives. Upon arrival of each message, the function must create * a new bound port that targets the sender's address and listening port, so that use of * this created bound port results in replying directly back to the sender. It is the * responsibility of this function to strip off and parse the header before returning the * data payload and data length via the respective msg and len parameter. The return value * of this function is the number of data payload bytes received not inclusive of the header. */ int minimsg_receive(miniport_t local_unbound_port, miniport_t* new_local_bound_port, minimsg_t msg, int *len) { int received; miniport_t port; network_interrupt_arg_t *intrpt; network_address_t dest_addr; mini_header_t header; unsigned short dest_port; interrupt_level_t oldlevel; if (NULL == local_unbound_port || NULL == new_local_bound_port || UNBOUNDED != local_unbound_port->type || NULL == len || BOUNDED == local_unbound_port->type) return -1; /* * These shared data structures can be changed in the newtwork interrupt * handler, so interrupts should be disabled here as well. */ oldlevel = set_interrupt_level(DISABLED); semaphore_P(local_unbound_port->unbound.ready); queue_wrap_dequeue(local_unbound_port->unbound.data, (void**) &intrpt); set_interrupt_level(oldlevel); /* * The copied size should be the minimum among the user provided buffer * size (original *len), the received data size (received), and * MINIMSG_MAX_MSG_SIZE. */ received = intrpt->size - MINIMSG_HDRSIZE; if (*len >= received) *len = received; if (*len >= MINIMSG_MAX_MSG_SIZE) *len = MINIMSG_MAX_MSG_SIZE; header = (mini_header_t) intrpt->buffer; unpack_address(header->source_address, dest_addr); dest_port = unpack_unsigned_short(header->source_port); port = miniport_create_bound(dest_addr, dest_port); if (NULL == port) return -1; *new_local_bound_port = port; memcpy(msg, header + 1, *len); free(intrpt); return received; }
int transmit_first(int* arg) { char buffer[MINIMSG_MAX_MSG_SIZE + 10]; int length = 0; int i; network_address_t hostaddr, targetaddr; miniport_t port; miniport_t dest; struct mini_header hdr; AbortOnCondition(network_translate_hostname(hostname, targetaddr) < 0, "Could not resolve hostname, exiting."); port = miniport_create_unbound(0); dest = miniport_create_bound(targetaddr, 1); /* Form correct header */ network_get_my_address(hostaddr); hdr.protocol = PROTOCOL_MINIDATAGRAM; pack_address(hdr.source_address, hostaddr); pack_unsigned_short(hdr.source_port, port->num); pack_address(hdr.destination_address, dest->bound.addr); pack_unsigned_short(hdr.destination_port, dest->bound.remote); /* Send packages with short but correct header and zero data */ printf("Sending packages with short headers.\n"); sprintf(buffer, "Receiving packages with short headers.\n"); length = strlen(buffer) + 1; minimsg_send(port, dest, buffer, length); for (i = 0; i < MINIMSG_HDRSIZE; i++) network_send_pkt(targetaddr, i, (char*)&hdr, 0, buffer); /* Send packages to wrong ports */ printf("Sending packages to wrong destination ports.\n"); sprintf(buffer, "Receiving packages with wrong destination ports.\n"); length = strlen(buffer) + 1; minimsg_send(port, dest, buffer, length); sprintf(buffer, "This message is sent to a wrong port.\n"); length = strlen(buffer) + 1; minimsg_send(port, miniport_create_bound(targetaddr, 0), buffer, length); minimsg_send(port, miniport_create_bound(targetaddr, MAX_UNBOUNDED), buffer, length); minimsg_send(port, miniport_create_bound(targetaddr, MAX_UNBOUNDED + 1), buffer, length); minimsg_send(port, miniport_create_bound(targetaddr, MIN_BOUNDED), buffer, length); minimsg_send(port, miniport_create_bound(targetaddr, MAX_BOUNDED), buffer, length); printf("Send-first finished.\n"); return 0; }
int thread(int* arg) { char buffer[BUFFER_SIZE]; int length = BUFFER_SIZE; miniport_t from; network_address_t my_address; network_get_my_address(&my_address); listen_port = miniport_create_unbound(0); send_port = miniport_create_bound(my_address, 0); minimsg_send(listen_port, send_port, text, textlen); minimsg_receive(listen_port, &from, buffer, &length); printf("%s", buffer); return 0; }
int thread(int* arg) { char buffer[BUFFER_SIZE]; int length = BUFFER_SIZE; miniport_t *from; network_address_t my_address; network_get_my_address(my_address); listen_port = miniport_create_unbound(0); send_port = miniport_create_bound(my_address, 0); minimsg_send(listen_port, send_port, text, textlen); minimsg_receive(listen_port, &from, buffer, &length); printf("%s\n", buffer); //newline is to enable printing when truncated before a newline character has been reached return 0; }
int transmit2(int* arg) { char buffer[BUFFER_SIZE]; int length; int i; miniport_t write_port; write_port = miniport_create_bound(my_address, 0); for (i=0; i<MAX_COUNT; i++) { printf("Sending packet %d from sender 2.\n", i+1); sprintf(buffer, "Count from sender 2 is %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port, write_port, buffer, length); minithread_yield(); } return 0; }
int minimsg_receive(miniport_t* local_unbound_port, miniport_t** new_local_bound_port, minimsg_t* msg, int *len) { assert(g_boundPortCounter >= 0); //sanity check to ensure minimsg_initialize() has been called first //validate input if (new_local_bound_port == NULL || local_unbound_port == NULL|| msg == NULL || len == NULL || *len < 0) return -1; assert(local_unbound_port->port_type == 'u' && local_unbound_port->unbound_port.datagrams_ready != NULL && local_unbound_port->unbound_port.datagrams_ready != NULL); semaphore_P(local_unbound_port->unbound_port.datagrams_ready); //P the semaphore, if the count is 0 we're blocked until packet arrives //once a packet arrives and we've woken network_interrupt_arg_t* dequeuedPacket = NULL; interrupt_level_t old_level = set_interrupt_level(DISABLED); // critical session (to dequeue the packet queue) assert(queue_length(local_unbound_port->unbound_port.incoming_data) > 0); //sanity check - our queue should have a packet waiting int dequeueSuccess = queue_dequeue(local_unbound_port->unbound_port.incoming_data, (void**)&dequeuedPacket); AbortOnCondition(dequeueSuccess != 0, "Queue_dequeue failed in minimsg_receive()"); set_interrupt_level(old_level); //end of critical session to restore interrupt level //Our packet size should be valid assert(dequeuedPacket->size >= 0); //get our header and message from the dequeued packet assert(dequeuedPacket->size >= sizeof(mini_header_t)); mini_header_t receivedHeader; memcpy(&receivedHeader, dequeuedPacket->buffer, sizeof(mini_header_t)); //set *len to the msg length to be copied: if the length of the message received is >= *len, no change to *len. Otherwise, set *len to the length of our received message if (dequeuedPacket->size - sizeof(mini_header_t) < *len) *len = dequeuedPacket->size - sizeof(mini_header_t); memcpy(msg, dequeuedPacket->buffer + sizeof(mini_header_t), *len); // msg is after header //create our new local bound port pointed back to the sender int sourcePort = (int)unpack_unsigned_short(receivedHeader.source_port); // get source's listening port assert(sourcePort >= UNBOUNDED_PORT_START && sourcePort <= UNBOUNDED_PORT_END); //make sure source port num is valid network_address_t remoteAddr; unpack_address(receivedHeader.source_address, remoteAddr); // get source's network address free(dequeuedPacket); // release the memory allocated to the packet *new_local_bound_port = miniport_create_bound(remoteAddr, sourcePort); // create a bound port if (*new_local_bound_port == NULL) return -1; return *len; //return data payload bytes received not inclusive of header }
int thread(int* arg) { char buffer[BUFFER_SIZE]; int length = BUFFER_SIZE; miniport_t from; network_address_t my_address; network_get_my_address(my_address); receive_port = miniport_create_unbound(0); send_port = miniport_create_bound(my_address, 0); minimsg_send(receive_port, send_port, text, textlen); minithread_sleep_with_timeout(1000); miniport_destroy(receive_port); receive_port = miniport_create_unbound(0); printf("waiting\n"); minimsg_receive(receive_port, &from, buffer, &length); printf("%s", buffer); //should not print return 0; }
int transmit(int* arg) { char buffer[BUFFER_SIZE]; int length; // int i; miniport_t write_port; network_address_t my_address; network_get_my_address(my_address); port = miniport_create_unbound(0); write_port = miniport_create_bound(my_address, 0); // write_port = miniport_create_bound("127.111.111.112", 0); // minithread_fork(receive, NULL); // for (i=0; i<MAX_COUNT; i++) { printf("Sending instant message:\n"); sprintf(buffer, "PUT INSTANT MESSAGE HERE\n"); length = strlen(buffer) + 1; minimsg_send(port, write_port, buffer, length); // } return 0; }
int transmit(int* arg) { char buffer[BUFFER_SIZE]; int length; int i; miniport_t *write_port; network_address_t my_address; network_get_my_address(my_address); port = miniport_create_unbound(0); write_port = miniport_create_bound(my_address, 0); minithread_fork(receive, NULL); for (i=0; i<MAX_COUNT; i++) { printf("Sending packet %d.\n", i+1); sprintf(buffer, "Count is %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port, write_port, buffer, length); } return 0; }
int transmit(int* arg) { char buffer[BUFFER_SIZE]; int length; network_address_t addr; miniport_t port; miniport_t dest; AbortOnCondition(network_translate_hostname(hostname, addr) < 0, "Could not resolve hostname, exiting."); port = miniport_create_unbound(42); dest = miniport_create_bound(addr, 42); minithread_fork(receive, NULL); while(1){ memset(buffer, 0, BUFFER_SIZE); length = miniterm_read(buffer, BUFFER_SIZE); minimsg_send(port, dest, buffer, length); } return 0; }
/* Receives a message through a locally unbound port. Threads that call this function are * blocked until a message arrives. Upon arrival of each message, the function must create * a new bound port that targets the sender's address and listening port, so that use of * this created bound port results in replying directly back to the sender. It is the * responsibility of this function to strip off and parse the header before returning the * data payload and data length via the respective msg and len parameter. The return value * of this function is the number of data payload bytes received not inclusive of the header. */ int minimsg_receive(miniport_t local_unbound_port, miniport_t* new_local_bound_port, minimsg_t msg, int *len) { unsigned short remote_port; char* buffer; // int size = 0; int i = 0; network_address_t remote_receive_addr; network_interrupt_arg_t* packet = NULL; // mini_header_t header; // semaphore_P(msgmutex); // Check for valid arguments if (local_unbound_port == NULL) { fprintf(stderr, "ERROR: minimsg_receive() passed a NULL local_unbound_port miniport argument\n"); semaphore_V(msgmutex); return -1; } if (new_local_bound_port == NULL) { fprintf(stderr, "ERROR: minimsg_receive() passed a NULL new_local_bound_port miniport* argument\n"); semaphore_V(msgmutex); return -1; } // semaphore_V(msgmutex); // fprintf(stderr, "minimsg_receive() paused\n"); semaphore_P(local_unbound_port->u.unbound.datagrams_ready); // Block until message arrives // fprintf(stderr, "minimsg_receive() resuming\n"); // semaphore_P(msgmutex); // Obtain received message from miniport queue and extract header data if (queue_dequeue(local_unbound_port->u.unbound.incoming_data, (void**) &packet) < 0) { fprintf(stderr, "ERROR: minimsg_receive() failed to dequeue message from miniport queue\n"); semaphore_V(msgmutex); return -1; } // Extract header stuff buffer = packet->buffer; // size = packet->size; // *len = ((packet->size) - 20) / sizeof(char); *len = sizeof(buffer[21]) / sizeof(char); unpack_address(&buffer[1], remote_receive_addr); remote_port = unpack_unsigned_short(&buffer[9]); // msg = (minimsg_t) &buffer[21]; // *msg = *((minimsg_t) &buffer[21]); while (buffer[21 + i]) { msg[i] = buffer[21 + i]; i++; } // fprintf(stderr, "minimsg_receive() past extracting header stuff\n"); /*fprintf(stderr, "minimsg_receive() msg: %s\n", msg); fprintf(stderr, "minimsg_receive() msg size: %d\n", (int) sizeof(msg)); fprintf(stderr, "minimsg_receive() len: %d\n", *len); fprintf(stderr, "minimsg_receive() force msg len: %d\n", (int) (sizeof((minimsg_t) &buffer[21]) / sizeof(char))); fprintf(stderr, "minimsg_receive() get body length: %lu\n", sizeof(buffer) / sizeof(buffer[21]) - 20);*/ // Create new bound port *new_local_bound_port = miniport_create_bound(remote_receive_addr, remote_port); //return number of bytes of payload actually received (drop stuff beyond max) free(packet); // semaphore_V(msgmutex); return sizeof(msg); }