Thread: Use one socket to send and receive message (using UDP)

  1. #1
    Registered User tanya9x's Avatar
    Join Date
    Feb 2010
    Location
    Moscow
    Posts
    4

    Wink Use one socket to send and receive message (using UDP)

    Hi everyone,

    I'm using socket API to make a simple chat program using UDP socket (SO_BROADCAST)

    To make it simple, at first, I created 1 socket named "socketa" in Application "AppA" to send message and created another socket "socketb" in Application "AppB" to receive message from "AppA". It worked perfectly, but only one-way.

    So, I want it to work in two-way communication, i.e. both send and receive message. I wonder whether I should create more sockets, e.g. "socketa2" in Application "AppA" to receive message and "socketb2" in Application "AppB" to send message?

    So, please tell me that can a socket both Send and Receive message? And how to design this two-way communication?

    I'm new to c++ and also windows socket, so I really appreciate someone giving me a detailed example how to do this.

    Thanks all.

  2. #2
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    If you use one socket, the communication will be synchronous. This means that B cant do anything until A has sent a message. Once A has sent and B has received, the opposite occurs: A cant do anything until B has sent a message. For a user program this isnt very intuitive, but it is good for "lower" level communication (but again, not for a chat program).

    You (or at least your users!) probably prefer to have asynchronous communication, so A and B can both send and receive. So you need two sockets, from A (write) to B (read), and B (write) to A (read). This asynchronous behaviour, however, means you need two threads, one to write to the socket and the other to read from the socket. If you've never worked with multi-threading, dont be scared off as it isnt overly complicated. Learning them and subsequently using asynchronous communication in the program will probably make it better all around.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by nadroj View Post
    If you use one socket, the communication will be synchronous. This means that B cant do anything until A has sent a message. Once A has sent and B has received, the opposite occurs: A cant do anything until B has sent a message. For a user program this isnt very intuitive, but it is good for "lower" level communication (but again, not for a chat program).

    You (or at least your users!) probably prefer to have asynchronous communication, so A and B can both send and receive. So you need two sockets, from A (write) to B (read), and B (write) to A (read). This asynchronous behaviour, however, means you need two threads, one to write to the socket and the other to read from the socket. If you've never worked with multi-threading, dont be scared off as it isnt overly complicated. Learning them and subsequently using asynchronous communication in the program will probably make it better all around.
    No offence, but you're wrong. First of all, this wasn't the question. Let me answer the question: there is no reason why a UDP socket can not both read and write. Use recvfrom and sendto to do this.
    But for a chat application TCP is better, since UDP is unreliable: packets might never arrive and you would never know unless you code your own way of knowing.

    Anyways, about the above post, the problem he talks about is that read/recv will usually block until there is data on the socket. But the solution is wrong: you don't need threads, and probably shouldn't.
    You can use either select/poll to find out if there is data pending on the socket. If there's not, then don't call read (same with write, you need to validate that you can write). Otherwise, use non-blocking sockets. I personally prefer poll as I think it's a bit faster if you do it properly.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    I'd like to know how I'm "wrong". Your answer was "yes", that a socket can be used for both read and write, which answers his/her first question. I never said it couldn't (maybe I should have answered that question stating that of course it can). My response was answering the next question
    And how to design this two-way communication?
    Also you say my solution is "wrong" and that threads aren't a good solution. I don't understand how you think the solution is "wrong" or that threads are a bad approach.

    All programmers know that there is (almost) always more than one correct "solution" (or "approach to solve a problem"). If you disagree or dont prefer my solution, then say so! Don't say it is "wrong", unless, of course, it is wrong. If it is, then please let me know exactly how it is "wrong" (i.e. doesn't solve the problem), and I'd be glad to learn from it.

  5. #5
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Quote Originally Posted by EVOEx View Post
    No offence, but you're wrong. First of all, this wasn't the question. Let me answer the question: there is no reason why a UDP socket can not both read and write. Use recvfrom and sendto to do this.
    But for a chat application TCP is better, since UDP is unreliable: packets might never arrive and you would never know unless you code your own way of knowing.

    Anyways, about the above post, the problem he talks about is that read/recv will usually block until there is data on the socket. But the solution is wrong: you don't need threads, and probably shouldn't.
    You can use either select/poll to find out if there is data pending on the socket. If there's not, then don't call read (same with write, you need to validate that you can write). Otherwise, use non-blocking sockets. I personally prefer poll as I think it's a bit faster if you do it properly.
    Yeah, poll is more efficient, which allows for more sockets, but doesn't make much difference in low-resource applications (chat servers are not low-resource).

    You can add your own protocol on top of UDP to ensure packets are handled in the correct order and depending on your needs it can still be more efficient than TCP.

    Quote Originally Posted by nadroj View Post
    I'd like to know how I'm "wrong". Your answer was "yes", that a socket can be used for both read and write, which answers his/her first question. I never said it couldn't (maybe I should have answered that question stating that of course it can). My response was answering the next questionAlso you say my solution is "wrong" and that threads aren't a good solution. I don't understand how you think the solution is "wrong" or that threads are a bad approach.

    All programmers know that there is (almost) always more than one correct "solution" (or "approach to solve a problem"). If you disagree or dont prefer my solution, then say so! Don't say it is "wrong", unless, of course, it is wrong. If it is, then please let me know exactly how it is "wrong" (i.e. doesn't solve the problem), and I'd be glad to learn from it.
    Aren't you wrong because if you use poll/select asynchronously recv doesn't block, and therefore you can use one socket for both sending and receiving? Threading is *a* solution though so I wouldn't say that suggestion in itself is wrong. However he probably meant suggesting the unnecessary (memory and complexity) overhead of using threads is wrong. Don't get me wrong though, in a high resource application you might use BOTH multiplexing poll and threading to keep the main thread clear (web servers).
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  6. #6
    Registered User tanya9x's Avatar
    Join Date
    Feb 2010
    Location
    Moscow
    Posts
    4
    Sorry, but I'm new to both c++ and socket. So, I can't understand both of you. For more details, I post some code here. I used MFC to develop GUI, so, the extracted code is not very neat and for simplicity, I don't mention some trivial code.

    This is code of AppA
    Code:
    // create socket to send message
    socketa = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
    char opt[2];opt[0] = 1;opt[1] = 0; 
    setsockopt(socketa, SOL_SOCKET, SO_BROADCAST,	opt, sizeof(opt));  // Broadcast socket
    
    // use broadcast address
    IN_ADDR addr; // 255,255,255,255; don't mention here
    SOCKADDR_IN sendaddress;
    sendaddress.sin_addr = addr; 
    sendaddress.sin_family = AF_INET;
    sendaddress.sin_port = htons(8009);
    
    // this is code to send message
    char buf[] = "hello world!"; // in fact, i get it from a textbox
    int len = (int) strlen(buf);
    sendto(socketa, (char FAR *)buf, len, 0,(const struct sockaddr FAR *)&sendaddress, sizeof(sendaddress));
    This is code of AppB
    Code:
    // create Non-Blocking socket to send message
    socketb = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
    unsigned long lNB = 1; // Non-Blocking socket
    ioctlsocket(socketb, FIONBIO, &lNB);
    // set address to local address
    SOCKADDR_IN receiveaddress;
    receiveaddress.sin_addr = localhostaddress(); // don't mention here
    receiveaddress.sin_family = AF_INET;
    receiveaddress.sin_port = htons(8009); 
    bind(socketb,(const SOCKADDR FAR*)&receiveaddress, sizeof(receiveaddress));
    // receive message
    recvfrom(socketb, (char FAR*)buf, BUFFER_SIZE, 0, NULL, NULL);
    This is how my program run, but only one-way communication. I tried to make it two-way, using the same socket. But how can I make it? I try to make some code, but it always throws very-hard-to-read-and-debug Exception. In fact, I think I can't debug when any Exception is thrown in C++ (

    Can you help me? I think it's a basic technique with someone who familiar with c++ and socket. Please help me out with some code. Thanks!!!

  7. #7
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by nadroj View Post
    All programmers know that there is (almost) always more than one correct "solution" (or "approach to solve a problem"). If you disagree or dont prefer my solution, then say so! Don't say it is "wrong", unless, of course, it is wrong. If it is, then please let me know exactly how it is "wrong" (i.e. doesn't solve the problem), and I'd be glad to learn from it.
    Wow, that sounded sarcastic. Well, okay, let me point out exactly where you were wrong:
    Quote Originally Posted by nadroj
    This asynchronous behaviour, however, means you need two threads, one to write to the socket and the other to read from the socket.
    Hence you stated one correct solution, saying that this was the needed solutions while it is not. So what you just posted seemed to apply perfectly to your post: all programmers know that there is (almost) always more than one correction solution. Not to say that usually it would be the most overkill of a solution.

    @tanya9x: Show us the code that sends the message back on the same socket, the bug is probably in there.
    Last edited by EVOEx; 02-26-2010 at 04:21 PM.

  8. #8
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Quote Originally Posted by Dae View Post
    Aren't you wrong because if you use poll/select asynchronously recv doesn't block, and therefore you can use one socket for both sending and receiving? Threading is *a* solution though so I wouldn't say that suggestion in itself is wrong. However he probably meant suggesting the unnecessary (memory and complexity) overhead of using threads is wrong.
    I was kinda confused by what you said here. No, as you said yourself, I'm not wrong because it is a solution. As I subtly said in my earlier response, I also thought that he probably meant it may not be as efficient or something, and didnt mean "wrong".

    I've never used "select" or "poll" functions myself, so I cant really help with an example of that. So hopefully these guys can help you out.

  9. #9
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Wow, that sounded sarcastic.
    Well I guess I failed at conveying my message again! In other words, I wasn't trying to be sarcastic.

    Now that you've been explicit, I see how you're correct about the use of "needed". Thanks for pointing that out.

  10. #10
    Registered User tanya9x's Avatar
    Join Date
    Feb 2010
    Location
    Moscow
    Posts
    4
    So, I think someone don't want to help me solve this problem.

  11. #11
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Quote Originally Posted by tanya9x View Post
    So, I think someone don't want to help me solve this problem.
    I think someone wants you to first take into consideration the suggestions and try them instead of expecting us to implement them for you. Either use poll(), select(), or threads, and come back if you need further help with the next step. Use Google (keywords and functions have already been named: poll, select, asynchronous, threading, multiplexing).
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  12. #12
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by tanya9x View Post
    So, I think someone don't want to help me solve this problem.
    As I said in my previous post:
    "@tanya9x: Show us the code that sends the message back on the same socket, the bug is probably in there. "

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Send a C Struct by UDP Socket C#
    By sergioms in forum C Programming
    Replies: 11
    Last Post: 09-10-2009, 08:49 AM
  2. Receive a TCP message on a UDP socket?
    By Yarin in forum C++ Programming
    Replies: 5
    Last Post: 09-05-2009, 12:21 AM
  3. socket error?
    By yahn in forum C++ Programming
    Replies: 5
    Last Post: 02-27-2006, 10:08 PM
  4. Client/Server Socket Receive Problem
    By mariabair in forum Networking/Device Communication
    Replies: 6
    Last Post: 12-25-2003, 10:01 AM
  5. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM