C++ chat client receives only after sending a message himself - c++

I am trying to write a little tcp chatroom in c++. When I connect one client to the server, the server receives correctly and can answer/echo if wanted. When I connect a second client and send a message with him to the server the other client receives that message too. But to receive the next messages of the other clients
When I have two clients connected to the server and the first client (C1) is sending, the other client (C2) receives that message correctly too. But from that point, that client (C2) has to send something himself in order to receive another message from client (C1). And the other way around. I hope thats understandable.
I thought that it has something to do with the fact that the "getline" is blocking from continueing to receiving again, so I tried to use threads but that didnt work either. Now I am thinking that I really has something to do with the streaming "property" of TCP.
Here is the server code:
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <arpa/inet.h>
#include <string.h>
#include <string>
#include <sys/select.h>
#include <fcntl.h>
#include <vector>
#include <thread>
using namespace std;
int main() {
// create server-socket
int listening = socket(AF_INET, SOCK_STREAM, 0);
fcntl(listening, F_SETFL, O_NONBLOCK);
if (listening == -1) {
cerr << "Failed to create socket." << endl;
return -1;
}
// bind socket to ip/port
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
inet_pton(AF_INET, "0.0.0.0", &hint.sin_addr);
// check if can bind
if (bind(listening, (sockaddr*)&hint, sizeof(hint)) == -1) {
cerr << "Failed to bind to IP/port" << endl;
return -2;
}
// check if can listen
if (listen(listening, SOMAXCONN) == -1) {
cerr << "Failed to listen." << endl;
return -3;
}
//
fd_set master;
FD_ZERO(&master);
FD_SET(listening, &master);
while (true) {
for (int i=0; i<=FD_SETSIZE; i++) {
if (FD_ISSET(i, &master)) {
int sock = i;
if(sock == listening) {
sockaddr_in client;
socklen_t clientSize = sizeof(client);
char host[NI_MAXHOST];
char svc[NI_MAXSERV];
int clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
FD_SET(clientSocket, &master);
string acceptMessage = "Successfully connected to the server.";
send(clientSocket, acceptMessage.c_str(), (acceptMessage.size() + 1), 0);
}
else {
char buffer[4096];
memset(buffer, 0, 4096);
// receive from client
int bytesReceived = recv(sock, buffer, 4096, MSG_DONTWAIT);
if (bytesReceived == -1) {
;
}
else if (bytesReceived == 0) {
close(sock);
FD_CLR(sock, &master);
cout << "Client disconnected." << endl;
}
else {
cout << "received: " << string(buffer, 0, bytesReceived) << endl;
for (int j=0; j<100; j++) {
int outSock = j;
if (FD_ISSET(j, &master)) {
if (outSock != listening && outSock != 63) {
if (outSock == sock) {
string echoMsg = "<echo>" + string(buffer, 0, bytesReceived);
send(outSock, echoMsg.c_str(), (echoMsg.size() + 1), 0);
;
}
else {
send(outSock, buffer, bytesReceived, 0);
}
}
}
}
}
}
}
}
}
return 0;
}
Here the client code:
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <arpa/inet.h>
#include <string.h>
#include <string>
#include <fcntl.h>
#include <future>
#include <thread>
using namespace std;
void *sendMessage(string userInput, int sock);
void *receiveMessage(char buffer[4096], int sock);
void *sendMessage(string userInput, int sock) {
// input message to send
cout << ">> ";
getline(cin, userInput);
// send message
int sendResult = send(sock, userInput.c_str(), userInput.size() + 1, 0);
if (sendResult == -1) {
cout << "Could not send to server." << endl;
}
}
void *receiveMessage(char buffer[4096], int sock) {
int bytesReceived = recv(sock, buffer, 4096, 0);
if (bytesReceived == -1) {
cout << "There has been a server-issue." << endl;
}
else if (bytesReceived == 0) {
cout << "Server closed." << endl;
}
else {
string receivedString = string(buffer, 0, bytesReceived);
string checkEcho = receivedString.substr(0, 6);
if (checkEcho.compare("<echo>") == 0) {
;
}
else {
cout << "SERVER: " << string(buffer, bytesReceived) << endl;
}
}
}
int main() {
// create socket
int sock = socket(AF_INET, SOCK_STREAM, 0);
//fcntl(sock, F_SETFL, O_NONBLOCK);
if (sock == -1) {
return 1;
}
// port and server-ip
int port = 54000;
string ipAddress = "127.0.0.1";
// create buffer for messages
char buffer[4096];
// ipv4 socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
// try connect to server
int connectResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connectResult == -1) {
cout << "Could not connect to server." << endl;
return -1;
}
else {
receiveMessage(buffer, sock);
}
string userInput;
while (true) {
// receive from server
memset(buffer, 0, 4096);
thread t1(sendMessage, userInput, sock);
thread t2(receiveMessage, buffer, sock);
//sendMessage(userInput, sock);
//receiveMessage(buffer, sock);
t1.join();
t2.join();
}
// close socket
close(sock);
return 0;
}
I have found some similiar questions but none could help me solve my problem.
This bugs me for quite some time now, so I'd really appreciate some answers :)

Related

Using std::thread for send and recive data from TCP socket

I'm developing a TCP socket client. I am trying to write a client that have individual thread for send and receive data. but when I use thread, get a runtime error.
The process goes like this:
main.cpp:
#include <iostream>
#include <thread>
#include <string>
#include <chrono>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#include "TCPConnection.h"
SOCKET sock;
void SendRecive(SOCKET *isock) {
// Do-While loop to send and recive data
char buf[4096];
while (true) {
// Prompt the user for some text
cout << "> ";
// Wait for response
ZeroMemory(buf, 4096);
auto byteRecived = recv(*isock, buf, 4096, 0);
if (byteRecived <= 0) continue;
// Echo response to console
cout << "SERVER> " << string(buf, 0, byteRecived) << endl;
}
}
using namespace std;
int main() {
TCPConnection tcpconn("192.168.1.4", 7705, &sock);
SendRecive(&sock);
return 0;
}
TCPConnection.h:
//
// Created by Hamed on 8/21/2021.
//
#ifndef TCPCLIENT_TCPCONNECTION_H
#define TCPCLIENT_TCPCONNECTION_H
#include <iostream>
#include <thread>
#include <string>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
class TCPConnection {
public:
SOCKET *isock;
TCPConnection(string ServerIPAddress, int ServerPort, SOCKET *sock);
~TCPConnection();
};
#endif //TCPCLIENT_TCPCONNECTION_H
TCPConnection.cpp:
#include "TCPConnection.h"
TCPConnection::TCPConnection(string ServerIPAddress, int ServerPort, SOCKET *sock) {
// Initialize WinSock
WSAData data{};
WORD ver = MAKEWORD(2, 2);
int wsResult = WSAStartup(ver, &data);
if (wsResult != 0) {
cerr << "Can't start winsock, Err #" << wsResult << endl;
return;
}
// Create socket
*sock = socket(AF_INET, SOCK_STREAM, 0);
if (*sock == INVALID_SOCKET) {
cerr << "Can't create socket, Err #" << WSAGetLastError() << endl;
WSACleanup();
return;
}
// Fill in a hint structure
sockaddr_in hint{};
hint.sin_family = AF_INET;
hint.sin_port = htons(ServerPort);
inet_pton(AF_INET, ServerIPAddress.c_str(), &hint.sin_addr);
// connect to server
int connResult = connect(*sock, (sockaddr *) &hint, sizeof(hint));
if (connResult == SOCKET_ERROR) {
cerr << "Can't connect to server, Err #" << WSAGetLastError() << endl;
closesocket(*sock);
WSACleanup();
return;
}
isock = sock;
}
TCPConnection::~TCPConnection() {
// Gracefully close down everything
closesocket(*isock);
WSACleanup();
}
this code working properly but when I change "main.cpp" to use thread like this:
int main() {
TCPConnection tcpconn("192.168.1.4", 7705, &sock);
thread DoRunTCPRecive(SendRecive,&sock);
return 0;
}
I get "Microsoft Visual C++ Runtime Library" debug error when runing app.
Update:
Actually I want to have a function for send and have another function for receive data . but when I use join, my code stay on current function and I can't run another code after that.
you should join the thread after create it
thread DoRunTCPRecive(SendRecive,&sock);
DoRunTCPRecive.join()

C++ TCP IP Client, send/recv messages overlap?

I am currently trying to create a C++ TCP IP Client that can send a specific string to a server, which makes the server send back a string with some numbers I need to use.
Specifically I need to send the string "getpos", and only that.
This works perfectly on the first loop, but on the second loop and onward. Whenever I try to send "getpos" again, it will overlap "getpos" with the numbers I previously recieved from the server and send that like:
"getpos20,123,24"
It's like the buffer or something hasn't cleared.
My program works perfectly when connecting to a Python server, but not a C++ server.
I have looked through others with similar issues, and tried various fixes. Nothing has worked so far.
Here is my current client code (on Linux):
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
#include <string>
int main()
{
// Create a socket
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
return 1;
}
// Create a hint structure for the server we're connecting with
int port = PORTHERE;
std::string ipAddress = "IPNUMBERHERE";
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
std::cout << "listening" << std::endl;
// Connect to the server on the socket
int connectRes = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connectRes == -1)
{
return 1;
}
std::cout << "connected" << std::endl;
// While loop:
char buf[4096];
int buflen = 1024;
while(true){
// Send to server
std::string getmypos = "getpos";
int sendRes = send(sock, getmypos.c_str(), getmypos.size(), 0);
if (sendRes == -1){
std::cout << "Could not send to server! Whoops!" << std::endl;
continue;
}
// Wait for response
memset(buf, 0, 4096);
int bytesReceived = recv(sock, buf, buflen, 0);
if (bytesReceived == -1)
{
std::cout << "There was an error getting response from server" << std::endl;
}
else
{
// Display response
std::cout << "SERVER> " << std::string(buf, bytesReceived) << std::endl;
sleep(1);
}
}
// Close the socket
close(sock);
return 0;
}

Sockets not sending data

I'm currently working on an instant messaging system that require a server and a client to communicate between each other.
I tried it in C++ using the default socket API.
The problem is that even if both programs (server & client) compile fine, there isn't any socket sent from the client that reaches the server.
I don't know what did I do wrong here (I went over my code like 5 times and even did it again from scratch, no success).
I used "debugs" messages to locate the problems and they all concern the processing loops that I use.
// code from the server
#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <stdlib.h>
#include <iostream>
#include <thread>
#include <vector>
#include <Ws2tcpip.h>
#include <string>
int main()
{
std::locale::global(std::locale("fr-FR"));
WSAData wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
std::cout << "Error initializing winsock";
return -1;
}
SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server == INVALID_SOCKET)
{
std::cout << "Error initializing the socket ";
return -2;
}
const unsigned short port = 9999;
sockaddr_in addr;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
addr.sin_family = AF_INET;
int res = bind(server, (sockaddr*)&addr, sizeof(addr));
if (res != 0)
{
std::cout << "Error when binding";
return -3;
}
res = listen(server, SOMAXCONN);
if (res != 0)
{
std::cout << "Error on calling listen";
return -4;
}
std::cout << "Server successfully launched" << std::endl;
char buffer[1025];
while (true)
{
sockaddr_in from = { 0 };
int addrlen = sizeof(from);
SOCKET newClient = accept(server, (SOCKADDR*)(&from), &addrlen);
if (newClient != SOCKET_ERROR)
{
std::cout << "Client connected successfully" << std::endl;
int Bytes = recv(newClient, buffer, 1024, 0);
if (Bytes <= 0)
{
break;
}
std::cout << "Message received from client : " << buffer << std::endl;
send(newClient, buffer, 1024, 0); // send it back to client
}
}
return 0;
}
// code from the client
#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <stdlib.h>
#include <iostream>
#include <thread>
#include <vector>
#include <Ws2tcpip.h>
#include <string>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
void sendMessage(SOCKET s);
void recvMessage(SOCKET s);
int main()
{
std::locale::global(std::locale("fr-FR"));
WSAData wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
std::cout << "Error initializing winsock";
return -1;
}
SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server == INVALID_SOCKET)
{
std::cout << "Error initializing the socket ";
return -2;
}
sockaddr_in addr;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_family = AF_INET;
addr.sin_port = htons(9999);
int res = bind(server, (sockaddr*)&addr, sizeof(addr));
if (res != 0)
{
std::cout << "Error when binding";
return -3;
}
if (connect(server, (const sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
std::cout << "Erreur when connecting : " << WSAGetLastError() << std::endl;
return -4;
}
std::cout << "You are connected to server" << std::endl;
std::thread sending(sendMessage, server);
std::thread receiving(recvMessage, server);
sending.detach();
receiving.detach();
while (true)
{ }
return 0;
}
void sendMessage(SOCKET s)
{
while (true)
{
std::string buff;
std::cout << "Type your message :" << std::endl;
std::getline(std::cin, buff);
std::cout << std::endl;
int Bytes = send(s, buff.c_str(), 1024, 0);
if (Bytes <= 0)
{
break;
}
}
}
void recvMessage(SOCKET s)
{
while (true)
{
char buffer[1025];
int Bytes = recv(s, buffer, 1024, 0);
if (Bytes <= 0)
{
break;
}
std::cout << "The server sent : " << buffer << std::endl;
}
}
The server should display the message that a client has connected when the client is launched and displays the chat command, but the only thing displayed in the server console is the message saying that the server has launched correctly... Yet the client displays the message supposedly "received" by the server.
PS : I'm aware the code doesn't need that many "include" statements, it's just I didn't remember which ones contained which functions so I'd rather include more than not enough for anybody wanting to compile the code.
Several Things:
First, this is wrong:
send(s, buff.c_str(), 1024, 0)
You're basically telling send that the buffer it addresses is a full 1kb, and to send it all. It hasn't a clue how much memory there is actually valid, and knows nothing about terminated strings.
Second, the client setup is wrong. Don't bind to a client socket; connect is sufficient. Notice these:
int res = bind(server, (sockaddr*)&addr, sizeof(addr));
if (res != 0)
{
std::cout << "Error when binding";
return -3;
}
if (connect(server, (const sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
std::cout << "Erreur when connecting : " << WSAGetLastError() << std::endl;
return -4;
}
That bind shouldn't be there. The connect will bind to the socket if the connection can be made. Removing the bind section of the client, fixing the buffer management to be correct, and putting closesocket calls where they belong, and your program will be much further down the road to functional. There are still some question logic workflows, but at least the connectivity will be setup better.

libev + non-blocking socket continuously invokes callback

I'm using libev + non-blocking sockets to send a request to a server. I'm using Keep Alive because I need to send future requests to the destination over this same connection.
Behavior
Run the program and it fetches the URL and logs to console, as expected.
After doing this, wait and don't push ctrl+c to exit the program.
Expected
App should stay open because event loop is waiting for future responses but should not console log anything after the initial response.
Actual
Leave the app running. After 30+ seconds, it will start to console log the same response over and over and over again without end.
Question
Why is libev calling my callback (example_cb) repeatedly when no new request was sent and no new response data was received? How can I fix this?
#include <ev.h>
#include <stdio.h>
#include <iostream>
#include <ctype.h>
#include <cstring>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
void sendRequest(int sockfd)
{
puts("------");
puts("sendRequest() was called");
stringstream ss;
ss << "GET /posts/11 HTTP/1.1\r\n"
<< "Host: jsonplaceholder.typicode.com\r\n"
<< "Accept: application/json\r\n"
<< "\r\n";
string request = ss.str();
if (send(sockfd, request.c_str(), request.length(), 0) != (int)request.length()) {
cout << "Error sending request." << endl;
exit(1);
}
cout << "Request sent. No err occured." << endl;
}
static void delay_cb(EV_P_ ev_timer *w, int revents)
{
puts("------");
puts("delay_cb() was called");
sendRequest(3);
}
static void example_cb(EV_P_ ev_io *w, int revents)
{
puts("------");
puts("example_cb() was called");
int sockfd = 3;
size_t len = 80*1024, nparsed; // response must be <= 80 Kb
char buf[len];
ssize_t recved;
recved = recv(sockfd, &buf, len, 0);
if (recved < 0) {
perror("recved was <1");
}
// don't process keep alives
if (buf[0] != '\0') {
std::cout << buf << std::endl;
}
// clear buf
buf[0] = '\0';
std::cout << "buf after clear attempt: " << buf << std::endl;
}
int example_request()
{
std::string hostname = "jsonplaceholder.typicode.com";
int PORT = 80;
struct sockaddr_in client;
struct hostent * host = gethostbyname(hostname.c_str());
if (host == NULL || host->h_addr == NULL) {
cout << "Error retrieving DNS information." << endl;
exit(1);
}
bzero(&client, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons( PORT );
memcpy(&client.sin_addr, host->h_addr, host->h_length);
// create a socket
int sockfd = socket(PF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
cout << "Error creating socket." << endl;
exit(1);
}
cout << "Socket created" << endl;
// enable keep alive
int val = 1;
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof val);
if (connect(sockfd, (struct sockaddr *)&client, sizeof(client)) < 0) {
close(sockfd);
cout << "Could not connect" << endl;
exit(1);
}
cout << "Socket connected" << endl;
// make non-blocking
int status = fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK);
if (status == -1) {
perror("ERROR making socket non-blocking");
}
std::cout << "Socket set to non-blocking" << std::endl;
std::cout << "Sockfd is: " << sockfd << std::endl;
return sockfd;
}
int main(void)
{
// establish socket connection
int sockfd = example_request();
struct ev_loop *loop = EV_DEFAULT;
ev_io example_watcher;
ev_io_init(&example_watcher, example_cb, sockfd, EV_READ);
ev_io_start(loop, &example_watcher);
// used to send the request 2 sec later
ev_timer delay_watcher;
ev_timer_init(&delay_watcher, delay_cb, 2, 0.0);
ev_timer_start(loop, &delay_watcher);
ev_run(loop, 0);
return 0;
}
Edit: Code updated with suggestions from comments
The source of the problem is that you do not check recved == 0 condition which corresponds to the other side closing the connection. When that happens the OS sets the socket into "closed mode" which (at least under linux) is always ready for reading and subsequent calls to recv will always return 0.
So what you need to do is to check for that condition, call close(fd); on the file descriptor (possibly with shutdown before) and ev_io_stop on the associated watcher. If you wish to continue at that point then you have to open a new socket and eo_io_start new watcher.

UDP Multicast recvfrom reading same datagram multiple times

I have a simple UDP multicast program in which the main thread spawns two worker threads. All three share one UDP multicast socket. Right now this program works, though the recvfrom call is happening twice per packet. Perhaps the first time it is called, it's not properly clearing the receive buffer? If so, how would I go about fixing this.
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string>
#include <pthread.h>
#include <unistd.h>
#define MULTICAST_PORT 23456
#define MULTICAST_ADDRESS "239.255.24.25"
#define MESSAGE_BUFFER_SIZE 256
using namespace std;
struct sockaddr_in sendaddr;
socklen_t sendaddrlen;
int sock;
string username;
pthread_mutex_t mut;
void print(string message) {
pthread_mutex_lock(&mut);
printf("%s\n", message.c_str());
pthread_mutex_unlock(&mut);
}
void *sender_actor(void *arg) {
// Prepare Message
string message = "ANNOUNCE " + username;
long bytes_sent;
while (true) {
print("sender thread: preparing to send message");
bytes_sent = sendto(sock, message.c_str(), message.length() + 1, 0, (struct sockaddr *)&sendaddr, sendaddrlen);
print("sender thread: sent message");
if (bytes_sent < 0) {
cerr << "sendto failed" << endl;
exit(EXIT_FAILURE);
}
sleep(60);
}
return 0;
}
void *recipient_actor(void *arg) {
// Declare Address
struct sockaddr_in other;
socklen_t otherlen;
// Prepare Buffer
long bytes_received;
char message_buffer[MESSAGE_BUFFER_SIZE];
while (true) {
print("receiver thread: preparing to receive message");
bytes_received = recvfrom(sock, message_buffer, MESSAGE_BUFFER_SIZE, 0, (struct sockaddr *)&other, &otherlen);
if (bytes_received < 0) {
cerr << "recvfrom failed" << endl;
exit(EXIT_FAILURE);
}
print("receiver thread: received message:");
print(message_buffer);
}
return 0;
}
int main(int argc, const char * argv[]) {
// Check arguments:
if (argc != 2) {
cerr << "invalid number of arguments" << endl;
exit(EXIT_FAILURE);
}
// Extract username:
username = argv[1];
// Create a UDP socket:
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (sock < 0) {
cerr << "failed to create socket" << endl;
exit(EXIT_FAILURE);
}
// Allow multiple sockets for the port:
u_int yes = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
perror("Reusing ADDR failed");
exit(1);
}
// Setup destination address:
struct sockaddr_in recvaddr;
memset(&recvaddr,0,sizeof(recvaddr));
recvaddr.sin_family = AF_INET;
recvaddr.sin_addr.s_addr = htonl(INADDR_ANY);
recvaddr.sin_port = htons(MULTICAST_PORT);
socklen_t recvaddrlen = sizeof(recvaddr);
// Bind the socket to the address:
if (bind(sock,(struct sockaddr *) &recvaddr, sizeof(recvaddr)) < 0) {
cerr << "bind failed" << endl;
exit(EXIT_FAILURE);
}
// Join multicast group:
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_ADDRESS);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
cerr << "setsockop failed" << endl;
exit(EXIT_FAILURE);
}
// Create sender thread:
pthread_t sender_thread;
pthread_create(&sender_thread, NULL, sender_actor, NULL);
// Create recipient thread:
pthread_t recipient_thread;
pthread_create(&recipient_thread, NULL, recipient_actor, NULL);
// Initialize Send Address
memset(&sendaddr,0,sizeof(sendaddr));
sendaddr.sin_family = AF_INET;
sendaddr.sin_addr.s_addr = inet_addr(MULTICAST_ADDRESS);
sendaddr.sin_port = htons(MULTICAST_PORT);
sendaddrlen = sizeof(sendaddr);
// Read input and send messages:
long bytes_sent;
string message;
while (true) {
getline(cin, message);
message = "FROM:" + username + " " + message;
print("main thread: preparing to send message");
bytes_sent = sendto(sock,message.c_str(), message.length() + 1, 0, (struct sockaddr *)&sendaddr, sendaddrlen);
print("main thread: sent message");
if (bytes_sent < 0) {
cerr << "sendto failed" << endl;
exit(EXIT_FAILURE);
}
}
return 0;
}