C/C++ Using send() in a loop, sending multiple messages










0














So what I'm trying to do is a server-client setup where client connects to a server and can send multiple various messages to the server which responds with certain message, depending on what was sent from the client, until message "close" closes the connection.



I got it working (modified an online example) but I'm not sure it's the right way to send multiple messages. The problem is, that in my case I cannot use send() function on a client side in a loop unless:



  • the code that creates a socket and connects to a server is in the same loop with send() on a client side, and accept() is in the same loop as read() on the server side, which doesn't seem right.

  • the code is before the loop on both sides, but in this case client can't reconnect.

Server:



 int main(int argc, char const *argv) SO_REUSEPORT, &opt, sizeof(opt))) 
perror("setsockopt");
exit(EXIT_FAILURE);


address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);

// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0)
perror("bind failed");
exit(EXIT_FAILURE);


if (listen(server_fd, 3) < 0)
perror("listen");
exit(EXIT_FAILURE);



// Accept
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0)
perror("accept");
exit(EXIT_FAILURE);


while (true)

// valread = read( new_socket , buffer, 1024);
// printf("Buffer: %sn",buffer );

// if (recv(new_socket, buffer, 1024, MSG_PEEK) > 0)
// printf("Buffer: %sn",buffer );
//

if (read(new_socket, buffer, 1024) > 0)
printf("Buffer: %sn", buffer);

bzero(buffer, 1024);


send(new_socket, hello, strlen(hello), 0);
printf("Hello message sentn");

return 0;



Client:



 int main(int argc, char const *argv) 
struct sockaddr_in address;
int sock = 0, valread;
struct sockaddr_in serv_addr;
// char *hello = "Hel0o from client";
char *hello;
char buffer[1024] = 0;

std::string msg;

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("n Socket creation error n");
return -1;


memset(&serv_addr, '0', sizeof(serv_addr));

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);

// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
printf("nInvalid address/ Address not supported n");
return -1;


if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
printf("nConnection Failed n");
return -1;


while (true)
std::cout << "msg: ";
std::cin >> msg;

hello = new char[msg.length() + 1];
std::strcpy(hello, msg.c_str());

send(sock , hello , strlen(hello) , 0 );


printf("Hello message sentn");
valread = read( sock , buffer, 1024);
printf("%sn",buffer );
return 0;



What would be the correct way of doing this?










share|improve this question

















  • 1




    Note: TCP does not deal in messages. It is a a stream of data. It is up to you to establish a protocol and place messages that adhere to that protocol in the stream. The recipient must continue reading until the entire message, as defined by the protocol, has been received You cannot simply printf("Buffer: %sn", buffer); because buffer may not be a null terminated string. bzero(buffer, 1024); tries, but cannot quite do the job. Try reading one byte less to leave room for the null. This staves off disaster, but does not establish a protocol.
    – user4581301
    Nov 11 at 17:47







  • 1




    Messages must be framed so the recipient knows where one message ends and the next begins. There are two ways to frame a message in TCP: send the message's length before sending the message's data, or end the message with a unique delimiter that never appears in the message data. The recipient can then read the message length followed by the specified amount of data, or can read until the delimiter is read.
    – Remy Lebeau
    Nov 11 at 19:55











  • Okay, but how do I code the server and the client for the client to be able to reconnect? Creating a new socket at client side each time I use send() and accepting new sockets every time I read surely can't be the right way to do it.
    – fingust
    Nov 12 at 17:04















0














So what I'm trying to do is a server-client setup where client connects to a server and can send multiple various messages to the server which responds with certain message, depending on what was sent from the client, until message "close" closes the connection.



I got it working (modified an online example) but I'm not sure it's the right way to send multiple messages. The problem is, that in my case I cannot use send() function on a client side in a loop unless:



  • the code that creates a socket and connects to a server is in the same loop with send() on a client side, and accept() is in the same loop as read() on the server side, which doesn't seem right.

  • the code is before the loop on both sides, but in this case client can't reconnect.

Server:



 int main(int argc, char const *argv) SO_REUSEPORT, &opt, sizeof(opt))) 
perror("setsockopt");
exit(EXIT_FAILURE);


address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);

// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0)
perror("bind failed");
exit(EXIT_FAILURE);


if (listen(server_fd, 3) < 0)
perror("listen");
exit(EXIT_FAILURE);



// Accept
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0)
perror("accept");
exit(EXIT_FAILURE);


while (true)

// valread = read( new_socket , buffer, 1024);
// printf("Buffer: %sn",buffer );

// if (recv(new_socket, buffer, 1024, MSG_PEEK) > 0)
// printf("Buffer: %sn",buffer );
//

if (read(new_socket, buffer, 1024) > 0)
printf("Buffer: %sn", buffer);

bzero(buffer, 1024);


send(new_socket, hello, strlen(hello), 0);
printf("Hello message sentn");

return 0;



Client:



 int main(int argc, char const *argv) 
struct sockaddr_in address;
int sock = 0, valread;
struct sockaddr_in serv_addr;
// char *hello = "Hel0o from client";
char *hello;
char buffer[1024] = 0;

std::string msg;

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("n Socket creation error n");
return -1;


memset(&serv_addr, '0', sizeof(serv_addr));

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);

// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
printf("nInvalid address/ Address not supported n");
return -1;


if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
printf("nConnection Failed n");
return -1;


while (true)
std::cout << "msg: ";
std::cin >> msg;

hello = new char[msg.length() + 1];
std::strcpy(hello, msg.c_str());

send(sock , hello , strlen(hello) , 0 );


printf("Hello message sentn");
valread = read( sock , buffer, 1024);
printf("%sn",buffer );
return 0;



What would be the correct way of doing this?










share|improve this question

















  • 1




    Note: TCP does not deal in messages. It is a a stream of data. It is up to you to establish a protocol and place messages that adhere to that protocol in the stream. The recipient must continue reading until the entire message, as defined by the protocol, has been received You cannot simply printf("Buffer: %sn", buffer); because buffer may not be a null terminated string. bzero(buffer, 1024); tries, but cannot quite do the job. Try reading one byte less to leave room for the null. This staves off disaster, but does not establish a protocol.
    – user4581301
    Nov 11 at 17:47







  • 1




    Messages must be framed so the recipient knows where one message ends and the next begins. There are two ways to frame a message in TCP: send the message's length before sending the message's data, or end the message with a unique delimiter that never appears in the message data. The recipient can then read the message length followed by the specified amount of data, or can read until the delimiter is read.
    – Remy Lebeau
    Nov 11 at 19:55











  • Okay, but how do I code the server and the client for the client to be able to reconnect? Creating a new socket at client side each time I use send() and accepting new sockets every time I read surely can't be the right way to do it.
    – fingust
    Nov 12 at 17:04













0












0








0







So what I'm trying to do is a server-client setup where client connects to a server and can send multiple various messages to the server which responds with certain message, depending on what was sent from the client, until message "close" closes the connection.



I got it working (modified an online example) but I'm not sure it's the right way to send multiple messages. The problem is, that in my case I cannot use send() function on a client side in a loop unless:



  • the code that creates a socket and connects to a server is in the same loop with send() on a client side, and accept() is in the same loop as read() on the server side, which doesn't seem right.

  • the code is before the loop on both sides, but in this case client can't reconnect.

Server:



 int main(int argc, char const *argv) SO_REUSEPORT, &opt, sizeof(opt))) 
perror("setsockopt");
exit(EXIT_FAILURE);


address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);

// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0)
perror("bind failed");
exit(EXIT_FAILURE);


if (listen(server_fd, 3) < 0)
perror("listen");
exit(EXIT_FAILURE);



// Accept
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0)
perror("accept");
exit(EXIT_FAILURE);


while (true)

// valread = read( new_socket , buffer, 1024);
// printf("Buffer: %sn",buffer );

// if (recv(new_socket, buffer, 1024, MSG_PEEK) > 0)
// printf("Buffer: %sn",buffer );
//

if (read(new_socket, buffer, 1024) > 0)
printf("Buffer: %sn", buffer);

bzero(buffer, 1024);


send(new_socket, hello, strlen(hello), 0);
printf("Hello message sentn");

return 0;



Client:



 int main(int argc, char const *argv) 
struct sockaddr_in address;
int sock = 0, valread;
struct sockaddr_in serv_addr;
// char *hello = "Hel0o from client";
char *hello;
char buffer[1024] = 0;

std::string msg;

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("n Socket creation error n");
return -1;


memset(&serv_addr, '0', sizeof(serv_addr));

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);

// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
printf("nInvalid address/ Address not supported n");
return -1;


if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
printf("nConnection Failed n");
return -1;


while (true)
std::cout << "msg: ";
std::cin >> msg;

hello = new char[msg.length() + 1];
std::strcpy(hello, msg.c_str());

send(sock , hello , strlen(hello) , 0 );


printf("Hello message sentn");
valread = read( sock , buffer, 1024);
printf("%sn",buffer );
return 0;



What would be the correct way of doing this?










share|improve this question













So what I'm trying to do is a server-client setup where client connects to a server and can send multiple various messages to the server which responds with certain message, depending on what was sent from the client, until message "close" closes the connection.



I got it working (modified an online example) but I'm not sure it's the right way to send multiple messages. The problem is, that in my case I cannot use send() function on a client side in a loop unless:



  • the code that creates a socket and connects to a server is in the same loop with send() on a client side, and accept() is in the same loop as read() on the server side, which doesn't seem right.

  • the code is before the loop on both sides, but in this case client can't reconnect.

Server:



 int main(int argc, char const *argv) SO_REUSEPORT, &opt, sizeof(opt))) 
perror("setsockopt");
exit(EXIT_FAILURE);


address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);

// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0)
perror("bind failed");
exit(EXIT_FAILURE);


if (listen(server_fd, 3) < 0)
perror("listen");
exit(EXIT_FAILURE);



// Accept
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0)
perror("accept");
exit(EXIT_FAILURE);


while (true)

// valread = read( new_socket , buffer, 1024);
// printf("Buffer: %sn",buffer );

// if (recv(new_socket, buffer, 1024, MSG_PEEK) > 0)
// printf("Buffer: %sn",buffer );
//

if (read(new_socket, buffer, 1024) > 0)
printf("Buffer: %sn", buffer);

bzero(buffer, 1024);


send(new_socket, hello, strlen(hello), 0);
printf("Hello message sentn");

return 0;



Client:



 int main(int argc, char const *argv) 
struct sockaddr_in address;
int sock = 0, valread;
struct sockaddr_in serv_addr;
// char *hello = "Hel0o from client";
char *hello;
char buffer[1024] = 0;

std::string msg;

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("n Socket creation error n");
return -1;


memset(&serv_addr, '0', sizeof(serv_addr));

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);

// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
printf("nInvalid address/ Address not supported n");
return -1;


if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
printf("nConnection Failed n");
return -1;


while (true)
std::cout << "msg: ";
std::cin >> msg;

hello = new char[msg.length() + 1];
std::strcpy(hello, msg.c_str());

send(sock , hello , strlen(hello) , 0 );


printf("Hello message sentn");
valread = read( sock , buffer, 1024);
printf("%sn",buffer );
return 0;



What would be the correct way of doing this?







c++






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 17:29









fingust

266




266







  • 1




    Note: TCP does not deal in messages. It is a a stream of data. It is up to you to establish a protocol and place messages that adhere to that protocol in the stream. The recipient must continue reading until the entire message, as defined by the protocol, has been received You cannot simply printf("Buffer: %sn", buffer); because buffer may not be a null terminated string. bzero(buffer, 1024); tries, but cannot quite do the job. Try reading one byte less to leave room for the null. This staves off disaster, but does not establish a protocol.
    – user4581301
    Nov 11 at 17:47







  • 1




    Messages must be framed so the recipient knows where one message ends and the next begins. There are two ways to frame a message in TCP: send the message's length before sending the message's data, or end the message with a unique delimiter that never appears in the message data. The recipient can then read the message length followed by the specified amount of data, or can read until the delimiter is read.
    – Remy Lebeau
    Nov 11 at 19:55











  • Okay, but how do I code the server and the client for the client to be able to reconnect? Creating a new socket at client side each time I use send() and accepting new sockets every time I read surely can't be the right way to do it.
    – fingust
    Nov 12 at 17:04












  • 1




    Note: TCP does not deal in messages. It is a a stream of data. It is up to you to establish a protocol and place messages that adhere to that protocol in the stream. The recipient must continue reading until the entire message, as defined by the protocol, has been received You cannot simply printf("Buffer: %sn", buffer); because buffer may not be a null terminated string. bzero(buffer, 1024); tries, but cannot quite do the job. Try reading one byte less to leave room for the null. This staves off disaster, but does not establish a protocol.
    – user4581301
    Nov 11 at 17:47







  • 1




    Messages must be framed so the recipient knows where one message ends and the next begins. There are two ways to frame a message in TCP: send the message's length before sending the message's data, or end the message with a unique delimiter that never appears in the message data. The recipient can then read the message length followed by the specified amount of data, or can read until the delimiter is read.
    – Remy Lebeau
    Nov 11 at 19:55











  • Okay, but how do I code the server and the client for the client to be able to reconnect? Creating a new socket at client side each time I use send() and accepting new sockets every time I read surely can't be the right way to do it.
    – fingust
    Nov 12 at 17:04







1




1




Note: TCP does not deal in messages. It is a a stream of data. It is up to you to establish a protocol and place messages that adhere to that protocol in the stream. The recipient must continue reading until the entire message, as defined by the protocol, has been received You cannot simply printf("Buffer: %sn", buffer); because buffer may not be a null terminated string. bzero(buffer, 1024); tries, but cannot quite do the job. Try reading one byte less to leave room for the null. This staves off disaster, but does not establish a protocol.
– user4581301
Nov 11 at 17:47





Note: TCP does not deal in messages. It is a a stream of data. It is up to you to establish a protocol and place messages that adhere to that protocol in the stream. The recipient must continue reading until the entire message, as defined by the protocol, has been received You cannot simply printf("Buffer: %sn", buffer); because buffer may not be a null terminated string. bzero(buffer, 1024); tries, but cannot quite do the job. Try reading one byte less to leave room for the null. This staves off disaster, but does not establish a protocol.
– user4581301
Nov 11 at 17:47





1




1




Messages must be framed so the recipient knows where one message ends and the next begins. There are two ways to frame a message in TCP: send the message's length before sending the message's data, or end the message with a unique delimiter that never appears in the message data. The recipient can then read the message length followed by the specified amount of data, or can read until the delimiter is read.
– Remy Lebeau
Nov 11 at 19:55





Messages must be framed so the recipient knows where one message ends and the next begins. There are two ways to frame a message in TCP: send the message's length before sending the message's data, or end the message with a unique delimiter that never appears in the message data. The recipient can then read the message length followed by the specified amount of data, or can read until the delimiter is read.
– Remy Lebeau
Nov 11 at 19:55













Okay, but how do I code the server and the client for the client to be able to reconnect? Creating a new socket at client side each time I use send() and accepting new sockets every time I read surely can't be the right way to do it.
– fingust
Nov 12 at 17:04




Okay, but how do I code the server and the client for the client to be able to reconnect? Creating a new socket at client side each time I use send() and accepting new sockets every time I read surely can't be the right way to do it.
– fingust
Nov 12 at 17:04

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251340%2fc-c-sys-socket-h-using-send-in-a-loop-sending-multiple-messages%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251340%2fc-c-sys-socket-h-using-send-in-a-loop-sending-multiple-messages%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Kleinkühnau

Makov (Slowakei)

Deutsches Schauspielhaus