| | |
Please make my frist socket app work...
Please support our C++ advertiser: Programming Forums - DaniWeb Sister Site
![]() |
Hey!! Ahh, all day I've been trying to learn something new, so reading over tutorials I compiled my first socket app!! The only problem is, it isn't working the way I would like it to, and I was hoping you gyus could help me figure out the problems.. I appologize if it is a little messy at this time, I'm quite distrought and ready to pull my hair out so I didn't yet take the care to fine-ture it and organize the code.. I'll do that once I can get it to work and figure out how to manipulate these damn sockets lol.. For the time being, i want to work with Datagram sockets, not streaming.. Thanks..
My app: I want it to be simple and console-based, you have two options: To send or receive a message. If you choose to send, you enter the receiver's IP address and a message to send to them. If the message is received, it is returned with an asterisk (*) appended to the end of it. If you choose to receive, the app will wait until a return-request is received, then it will return the data with an asterisk (*) appended to the end of it.. Simple? Yea.. I will make it more advanced etc after I can get the following working properly, please help me with that:
The problems I've encountered: Can't retrieve my own IP address (I found out that was because INADDR_ANY is equal to zero).. When sending or waiting for data, the console kinda goes neutral and I can type and stuff when I shouldn't be able to.. It won't continue through the code, perhaps it's waiting for the receiving computer to respond with an ACK... Hmm, please heeeeellllppppp!!!! :cheesy:
My app: I want it to be simple and console-based, you have two options: To send or receive a message. If you choose to send, you enter the receiver's IP address and a message to send to them. If the message is received, it is returned with an asterisk (*) appended to the end of it. If you choose to receive, the app will wait until a return-request is received, then it will return the data with an asterisk (*) appended to the end of it.. Simple? Yea.. I will make it more advanced etc after I can get the following working properly, please help me with that:
C++ Syntax (Toggle Plain Text)
// My First Internet Application // By Matthew Cudmore, 2005 #include <iostream> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> // For gethostname #define MYPORT 4689 #define QUEMAX 10 using namespace::std; int main(void) { int sockfd, new_fd, sin_size; socklen_t sl = sizeof(struct sockaddr); struct sockaddr_in my_addr; // my address information struct sockaddr_in their_addr; // connector's address information // SOCK_STREAM or SOCK_DGRAM if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){ // ERROR cout << "\n-- SOCKET error\n"; return 0; } my_addr.sin_family = AF_INET; // host byte order their_addr.sin_family = AF_INET; // Choose one method: // 1) my_addr.sin_port = htons(MYPORT); // short, network byte order // 2) my_addr.sin_port = htons(0); // choose an unused port at random my_addr.sin_port = htons(MYPORT); // short, network byte order their_addr.sin_port = htons(MYPORT); // Choose one method: // 1) my_addr.sin_addr.s_addr = inet_addr("10.12.110.57"); // 2) inet_aton("10.12.110.57", &(my_addr.sin_addr)); // 3) my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // use my IP address my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // use my IP address memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { // ERROR cout << "\n-- BIND error\n"; return 0; } // ################################################################### char Buffer[100]; int BtsMvd; cout << "Simple sockets by Matthew Cudmore...\n"; cout << "Your IP: " << inet_ntoa(my_addr.sin_addr) << "\n"; GetChoice: cout << "\nEnter choice action (x = exit, s = send, a = accept): "; cin.getline(Buffer, 99); if (Buffer[0] == 'x') { close (sockfd); return 0; } else if (Buffer[0] == 's') { cout << "Enter the IP of the receiving machine: "; cin.getline(Buffer, 99); their_addr.sin_addr.s_addr = inet_addr(Buffer); memset(&(their_addr.sin_zero), '\0', 8); cout << "Enter a message to send to the receiving machine: "; cin.getline(Buffer, 99); if ((BtsMvd = sendto(sockfd, Buffer, strlen(Buffer), 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) != -1){ cout << "\nMessage sent. Awaiting reply..."; } else { cout << "\nMessage could not be sent."; goto GetChoice; } while (1) { if ((BtsMvd = recvfrom(sockfd, Buffer, strlen(Buffer), 0, (struct sockaddr *)&their_addr, &sl)) == -1) { // ERROR cout << "\n-- recvfrom error\n"; return 0; } if (BtsMvd) { if (Buffer[BtsMvd - 1] == '*') { cout << "\nReturn received."; break; } else { cout << "\nReturn-request ignored."; } } } } else if (Buffer[0] == 'a') { cout << "Waiting for incoming return-requests..."; BtsMvd = 0; while (1) { if ((BtsMvd = recvfrom(sockfd, Buffer, strlen(Buffer), 0, (struct sockaddr *)&their_addr, &sl)) == -1) { // ERROR cout << "\n-- recvfrom error\n"; return 0; } if (BtsMvd) break; } cout << "\nReturn-request received from: " << inet_ntoa(their_addr.sin_addr); BtsMvd = strlen(Buffer); Buffer[BtsMvd] = '*'; Buffer[BtsMvd + 1] = '\0'; if ((BtsMvd = sendto(sockfd, Buffer, strlen(Buffer), 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) > 0){ cout << "\nA return (" << Buffer << ") has been sent back."; } else { cout << "\nCould not return request."; } } goto GetChoice; return 0; }
The problems I've encountered: Can't retrieve my own IP address (I found out that was because INADDR_ANY is equal to zero).. When sending or waiting for data, the console kinda goes neutral and I can type and stuff when I shouldn't be able to.. It won't continue through the code, perhaps it's waiting for the receiving computer to respond with an ACK... Hmm, please heeeeellllppppp!!!! :cheesy:
Here is a running code. You will have to clean it up more. The errors you made were not in the socket creation. This is what the Stevens Book say for bind at INADDR_ANY
Hence you see the The errors were in specifying the amount of data to be received and sent using the recvfrom and sendto functions. You will understand while looking at my code.
Another thing, I am not good in Linux Programming, but I think there should be a way of determining the specific error that occurred under some function. e.g GetLastError in Windows. Find that. Then it will be easier to find out errors in your program. And if you are thinking of doing some serious network programming better to buy UNIX® Network Programming Volume by W.R. Stevens.
C++ Syntax (Toggle Plain Text)
// My First Internet Application // By Matthew Cudmore, 2005 #include <iostream> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> // For gethostname #define MYPORT 4689 #define QUEMAX 10 #define BUFFER_LEN 100 #ifndef SOCKET_ERROR #define SOCKET_ERROR -1 #endif using namespace::std; int main(void) { int sockfd, new_fd, sin_size; int sl = sizeof(struct sockaddr); struct sockaddr_in my_addr; // my address information struct sockaddr_in their_addr; // connector's address information // SOCK_STREAM or SOCK_DGRAM if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR ) { // ERROR cout << "\n-- SOCKET error\n"; return 0; } my_addr.sin_family = AF_INET; // host byte order their_addr.sin_family = AF_INET; // Choose one method: // 1) my_addr.sin_port = htons(MYPORT); // short, network byte order // 2) my_addr.sin_port = htons(0); // choose an unused port at random my_addr.sin_port = htons(MYPORT); // short, network byte order their_addr.sin_port = htons(MYPORT); // Choose one method: // 1) my_addr.sin_addr.s_addr = inet_addr("10.12.110.57"); // 2) inet_aton("10.12.110.57", &(my_addr.sin_addr)); // 3) my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // use my IP address my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // use my IP address memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct if (bind(sockfd, (struct sockaddr *)&my_addr,sizeof(struct sockaddr)) == SOCKET_ERROR) { // ERROR cout << "\n-- BIND error\n"; return 0; } // ################################################################### char Buffer[BUFFER_LEN]; int BtsMvd; cout << "Simple sockets by Matthew Cudmore...\n"; cout << "Your IP: " << inet_ntoa(my_addr.sin_addr) << "\n"; GetChoice: cout << "\nEnter choice action (x = exit, s = send, a = accept): "; cin.getline(Buffer, 99); if (Buffer[0] == 'x') { closesocket(sockfd); return 0; } else if (Buffer[0] == 's') { cout << "Enter the IP of the receiving machine: "; cin.getline(Buffer, 99); their_addr.sin_addr.s_addr = inet_addr(Buffer); memset(&(their_addr.sin_zero), '\0', 8); cout << "Enter a message to send to the receiving machine: "; cin.getline(Buffer, 99); if ((BtsMvd = sendto(sockfd, Buffer, sizeof(Buffer), 0,(struct sockaddr *)&their_addr, sizeof(struct sockaddr))) != -1) { cout << "\nMessage sent. Awaiting reply..."; } else { cout << "\nMessage could not be sent."; goto GetChoice; } while (1) { if ((BtsMvd = recvfrom(sockfd, Buffer, sizeof(Buffer), 0,(struct sockaddr *)&their_addr, &sl)) == -1) { // ERROR cout << "\n-- recvfrom error\n"; return 0; } if ( BtsMvd ) { BtsMvd = strlen(Buffer); if (Buffer[ BtsMvd - 1 ] == '*') { cout << "\nReturn received."; break; } else { cout << Buffer<<" \nReturn-request ignored."; } } } } else if (Buffer[0] == 'a') { cout << "Waiting for incoming return-requests..."; BtsMvd = 0; while (1) { if ((BtsMvd = recvfrom(sockfd, Buffer, sizeof(Buffer), 0,(struct sockaddr *)&their_addr, &sl)) == SOCKET_ERROR) { // ERROR cout << "\n-- recvfrom error\n"; return 0; } if (BtsMvd) { break; } } cout << "\nReturn-request received from: " << inet_ntoa(their_addr.sin_addr); BtsMvd = strlen(Buffer); Buffer[ BtsMvd ] = '*'; Buffer[ BtsMvd + 1 ] = '\0'; their_addr.sin_family = AF_INET; their_addr.sin_port = htons(MYPORT); their_addr.sin_addr.s_addr =inet_addr( inet_ntoa(their_addr.sin_addr) ); memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct if ((new_fd = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR) { // ERROR cout << "\n-- SOCKET error\n"; return 0; } if ((BtsMvd = sendto(new_fd, Buffer, sizeof(Buffer), 0,(struct sockaddr *)&their_addr, sizeof(struct sockaddr))) != SOCKET_ERROR ) { cout << "\nA return (" << Buffer << ") has been sent back."; } else { cout << "\nCould not return request."; } } goto GetChoice; return 0; }
•
•
•
•
But if we specify a wildcard IP address, the kernel does not choose the local IP address until either the socket is connected (TCP) or a datagram is sent on the socket (UDP).
C++ Syntax (Toggle Plain Text)
Your IP: 0.0.0.0
Another thing, I am not good in Linux Programming, but I think there should be a way of determining the specific error that occurred under some function. e.g GetLastError in Windows. Find that. Then it will be easier to find out errors in your program. And if you are thinking of doing some serious network programming better to buy UNIX® Network Programming Volume by W.R. Stevens.
Alrightie then... I think all is well, and I've organized it a little more and taken care of that local IP-thing.. Now all that is left is to test it with someone running a Linux and see how it works, then improve it from there... Here is how I found my local IP:
Is that good enough? It shows me what I want to see, based on http://whatismyip.com/ but is there a better way to do this?? Oh, and when I am looking to recvfrom, the terminal will let me type freely while it waits to receive, actually the code *apparently* stops at that command until something is received, and it won't continue on until something actually is received lol.. Is there some way to fix this? I eitehr want to prevent the user from being able to type at the terminal while the wait is taking place, or better yet, cancel the wait after so many seconds, print "No return was received", then goto GetChoice.... Any ideas? thanks!! :mrgreen:
C++ Syntax (Toggle Plain Text)
char Buffer[100]; struct hostent *h; // MEEEEE if (gethostname(Buffer, sizeof(Buffer))) { // ERROR cout << "\n-- HOST error 1\n"; return 0; } if ((h = gethostbyname(Buffer)) == 0x0) { // ERROR cout << "\n-- HOST error 2\n"; return 0; } cout << "Your IP: " << inet_ntoa(*((struct in_addr *)h->h_addr)) << "\n";
Is that good enough? It shows me what I want to see, based on http://whatismyip.com/ but is there a better way to do this?? Oh, and when I am looking to recvfrom, the terminal will let me type freely while it waits to receive, actually the code *apparently* stops at that command until something is received, and it won't continue on until something actually is received lol.. Is there some way to fix this? I eitehr want to prevent the user from being able to type at the terminal while the wait is taking place, or better yet, cancel the wait after so many seconds, print "No return was received", then goto GetChoice.... Any ideas? thanks!! :mrgreen:
Hmm, on the top of my head the timeout thingie should be easiest to implement, I think. Atleast if you know soemthing about signaling, check man signal and man alarm (idea: signal( SIGALRM, IgnoreFunc ) ; alarm(timeout) ; recvfrom(...) ; check return code ; alarm(0) ; signal( SIGALRM, OldFunc ) )...
Atlernative could be asynchronus io with select (man select) or thread/processes using fork/pthreads...
I assume you could do something to skip input also, not sure how though, perhaps discard all input after you return from recvfrom ?
Well, I checked recvfrom man page and it also sugests poll for checking if data is availbile, how ever now it seems as if I am getting incoherent and any further ramblings are likely to be crapp so Ill stop (since I dont have paitence to reread what I've written)...
Btw the error value of functions can be found with errno (#include <errno.h> iirc)... and you can get a printing of the error reason with perror("description") but I think that function exists the program though...
Atlernative could be asynchronus io with select (man select) or thread/processes using fork/pthreads...
I assume you could do something to skip input also, not sure how though, perhaps discard all input after you return from recvfrom ?
Well, I checked recvfrom man page and it also sugests poll for checking if data is availbile, how ever now it seems as if I am getting incoherent and any further ramblings are likely to be crapp so Ill stop (since I dont have paitence to reread what I've written)...
Btw the error value of functions can be found with errno (#include <errno.h> iirc)... and you can get a printing of the error reason with perror("description") but I think that function exists the program though...
/pern.*/i
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
![]() |
Similar Threads
- How to make CSS opacity setting work in IE7 ? (JavaScript / DHTML / AJAX)
- how to make app always on top (VB.NET)
- Scktcomp not work!! (Pascal and Delphi)
- My yahoo client. Not receiving data in real time :(( Just need a bit of advice (Perl)
- Linksys router; help in getting it to work (Networking Hardware Configuration)
Other Threads in the C++ Forum
- Previous Thread: need some help please
- Next Thread: Searching a file for a string
Views: 3905 | Replies: 3
| Thread Tools | Search this Thread |
Tag cloud for C++
6 api application array arrays assignment beginner binary bitmap c++ c/c++ calculator char class classes code coding compile compiler console conversion convert count data database delete developer display dll email encryption error file forms fstream function functions game generator getline givemetehcodez graph homeworkhelper iamthwee ifstream image input int java lazy lib loop looping loops map math matrix memory multidimensional multiple newbie news node number output parameter pointer problem program programming project proxy python random read recursion recursive reference return sort sorting string strings struct template templates text tree url variable vector video visual visualstudio win32 windows winsock word wordfrequency wxwidgets






