/* Chat program proof-of-concept using UDP. Tested on Bridged Mode with two VMs under the same router (same and different computers), and on NAT Network Mode with two VMs using the same virtualized NAT. */ U8 *dest_ip_string = GetStr("Destination IPV4: "), *port_string = GetStr("RX & TX UDP Port: "); CIPV4Address *dest_address = CAlloc(sizeof(CIPV4Address)); I64 port = Str2I64(port_string); CTask *chat_display_task = NULL; CTask *chat_message_task = NULL; U0 ChatDisplayTask(I64) {// display received messages. DocTermNew; DocCursor; DocPrint(, "$WW,1$"); while (TaskValidate(chat_message_task)) { Refresh; } } U0 ChatMsgTask(I64) {// take in text. U8 *message; I64 de_index; U8 *payload; DocTermNew; DocPrint(, "$WW,1$"); while (message = GetStr("> ",, GSF_SHIFT_ESC_EXIT)) { DocBottom(chat_display_task->put_doc); DocPrint(chat_display_task->put_doc, "$BG,BLUE$$BLACK$<local>$FG$$BG$ %s\n", message); de_index = UDPPacketAllocate(&payload, ipv4_globals.local_ip, port, dest_address->address, port, StrLen(message)); MemCpy(payload, message, StrLen(message)); UDPPacketFinish(de_index); DocClear; DocPrint(, "$WW,1$"); } } U0 ChatInit() { chat_message_task = Spawn(&ChatMsgTask, NULL, "UDP Chat Msg"); chat_display_task = Spawn(&ChatDisplayTask, NULL, "UDP Chat"); chat_message_task->win_inhibit = WIG_USER_TASK_DFT; chat_display_task->win_inhibit = WIG_USER_TASK_DFT; LBts(&chat_message_task->display_flags, DISPLAYf_SHOW); LBts(&chat_display_task->display_flags, DISPLAYf_SHOW); WinFocus(chat_display_task); WinFocus(chat_message_task); chat_display_task->win_top = 2; chat_display_task->win_bottom = TEXT_ROWS / 3; chat_display_task->win_left = TEXT_COLS / 3; chat_display_task->win_right = TEXT_COLS / 3 * 2; chat_message_task->win_top = chat_display_task->win_bottom + 2; chat_message_task->win_bottom = chat_message_task->win_top + 3; chat_message_task->win_left = chat_display_task->win_left; chat_message_task->win_right = chat_display_task->win_right; } U0 Chat() { CUDPSocket *udp_socket = UDPSocket(AF_INET); CSocketAddressIPV4 *sock_addr = CAlloc(sizeof(CSocketAddressIPV4)); U8 *buffer[ETHERNET_FRAME_SIZE]; // MemSet(buffer, 0, ETHERNET_FRAME_SIZE); "\nIP entered: %s\n" , dest_ip_string; while (PresentationToNetwork(AF_INET, dest_ip_string, dest_address) == -1) { "ERROR: Bad IP entered. Retry.\n"; dest_ip_string = GetStr("Destination IPV4: "); } ChatInit; sock_addr->port = EndianU16(port); sock_addr->family = AF_INET; sock_addr->address.address = dest_address->address; UDPSocketBind(udp_socket, sock_addr); "\nIP entered: %s\n" , dest_ip_string; while (TaskValidate(chat_message_task)) { if (UDPSocketReceiveFrom(udp_socket, buffer, ETHERNET_FRAME_SIZE, NULL) != -1) { DocBottom(chat_display_task->put_doc); DocPrint(chat_display_task->put_doc, "$BG,PURPLE$$BLACK$<%s>$FG$$BG$ %s\n", dest_ip_string, buffer);//NetworkToPresentation(AF_INET, dest_address)); MemSet(buffer, 0, ETHERNET_FRAME_SIZE); } Refresh; } Free(sock_addr); UDPSocketClose(udp_socket); } Chat;