Jump to content
  • Advertisement
Sign in to follow this  
xIshtarx

Same socket for sending and receivng?

This topic is 5394 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ive read 'Beej's Networking Tutorials' just like the FAQ tells me too. And i tried to change the UDP talker-lister programm a bit, so the listener would sent an acknowledgement packet. But I can't use the socket with wich i send data to receive data aswell. What i do is this: sockfd=socket(AF_INET, SOCK_DGRAM, 0); bind(sockfd,...); sendto(sockfd, message,...); recvfrom(sockfd,buf,...); recvfrom then gives an error: "recvfrom: No Error" (perror("recvfrom");) So do i need another socket for receiving, or am i just being stupid? I use Visual C++ and <winsock.h> Thanks for reading this

Share this post


Link to post
Share on other sites
Advertisement
In UDP, you can send and receive on the same socket.

However, if the socket is non-blocking, then calling recvfrom() will immediately return, even if there is no data.

Also, if you run two copies of the same program on the same machine, they can't both bind to the same port -- don't know if this is your problem or not -- it doesn't even really say what the actual error would be (your detection/printing code isn't part of the pasted code).

Share this post


Link to post
Share on other sites
well this is the source that i use. I copied it from the tutorial and changed it a bit for Visual C++. And the two programs worked. Then i just added Bind() and Recvfrom() to be able to send with the socket aswell.Its a regular blocking socket. If you compile it ull see what the problem is.


#define THEIRPORT 4950 // the port users will be connecting to
#define MYPORT 4949

#include <winsock.h>
#include <iostream.h>

#define MAXBUFLEN 100

int main()
{
WSAData wsaData;//
WSAStartup(MAKEWORD(2, 2), &wsaData);
char buf[MAXBUFLEN];

int sockfd;
struct sockaddr_in their_addr,my_addr; // connector's address information
struct hostent *he;
int numbytes;
char message[100];
cin >> message;

my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct

if ((he=gethostbyname("Ramon")) == NULL) { // get the host info
perror("gethostbyname");
cout << "Coulnt find host";
char chr[10];
cin >> chr;
exit(1);
}

their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(THEIRPORT); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct


if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
cout << "Socket error";
char chr[10];
cin >> chr;
exit(1);
}
if (bind(sockfd, (struct sockaddr *)&my_addr,
sizeof(struct sockaddr)) == -1) {
perror("bind");
char chr[10];
cin >> chr;
exit(1);
}

if ((numbytes=sendto(sockfd, message, strlen(message), 0,
(struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {
perror("sendto");
exit(1);
}

cout << numbytes <<" bytes where send to "
<< inet_ntoa(their_addr.sin_addr) <<endl;

int addr_len = sizeof(struct sockaddr);

if ((numbytes=recvfrom(sockfd,buf, MAXBUFLEN-1, 0,
(struct sockaddr *)&their_addr,&addr_len)) == -1) {
perror("recvfrom");

char chr[10];
cin >> chr;
exit(1);//and this is where the programm stops
}
cout << numbytes << " received" << endl;
cout << buf << endl;

closesocket(sockfd);

char chr[10];
cin >> chr;
return 0;
}


Share this post


Link to post
Share on other sites
yay i fixed it. The problem was that the packet, that i send first, needs to be received, by the other programm, before i can recv a packet with the same socket. So i just added Sleep(100); and it works :)
Thanks anyway hplus0603!

Share this post


Link to post
Share on other sites
Quote:
Original post by xIshtarx
yay i fixed it. The problem was that the packet, that i send first, needs to be received, by the other programm, before i can recv a packet with the same socket. So i just added Sleep(100); and it works :)


Although this might smell like a nice fix right now, this isn't a good way to go about doing things. What if you are experiencing lag, and it takes more than 100ms for the packet to get back to you? Or what if another packet gets there ahead of the one you're expecting?

For your example, waiting is sufficient. Just keep these pitfalls in mind for when you write your next project. ;)

Share this post


Link to post
Share on other sites
Thanks for the feedback.
It's my first networking programm, just to learn how UDP works. Btw if i want it non-blocking, i just use this?:
fcntl(sockfd, F_SETFL, O_NONBLOCK);
I dunno it it works for UDP aswell and that tutorial said:

Generally speaking, however, this type of polling is a bad idea. If you put your program in a busy-wait looking for data on the socket, you'll suck up CPU time like it was going out of style. A more elegant solution for checking to see if there's data waiting to be read comes in the following section on select().

I dont understand, why it would suck up CPU time. Can u use select on udp sockets aswell?

Share this post


Link to post
Share on other sites
It would suck up CPU time because if your socket is nonblocking, you'd just write a while() loop, looping while the return value is WSAEWOULDBLOCK, something like this:
do {
int nRet = recv(...);
} while((nRet == -1) && (WSAGetLastError() == WSAEWOULDBLOCK));


select() allows your thread to sleep until a a message arrives.
Yes, you can use select() on UDP sockets.

Share this post


Link to post
Share on other sites
Do i really need to use threads? or can i just do something like this?

while(true){
Recv();
Send();
UpdateGame();
RenderGame();
}
Becus currently my game sucks up all the CPU time anyway :)
Could u point me some tutorials about multithreading (for networking)?

Share this post


Link to post
Share on other sites
xIshtarx,

You don't need to use threads. In fact, the FAQ suggests that threads seldom help with networking games, and often hurt a bit.

The loop you suggest will work fine for a simple networked game, using non-blocking sockets. Once you get a little more fancy, you probably want to update physics on a fixed time-step basis, but keep the rest of the loop the same (including animation, which can run separate from physics).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!