943,984 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 6271
  • C++ RSS
Nov 27th, 2005
0

Please make my frist socket app work...

Expand Post »
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:

C++ Syntax (Toggle Plain Text)
  1. // My First Internet Application
  2. // By Matthew Cudmore, 2005
  3.  
  4. #include <iostream>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <unistd.h> // For gethostname
  10.  
  11. #define MYPORT 4689
  12. #define QUEMAX 10
  13.  
  14. using namespace::std;
  15.  
  16. int main(void) {
  17.  
  18. int sockfd, new_fd, sin_size;
  19. socklen_t sl = sizeof(struct sockaddr);
  20. struct sockaddr_in my_addr; // my address information
  21. struct sockaddr_in their_addr; // connector's address information
  22.  
  23. // SOCK_STREAM or SOCK_DGRAM
  24. if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
  25. // ERROR
  26. cout << "\n-- SOCKET error\n";
  27. return 0;
  28. }
  29.  
  30. my_addr.sin_family = AF_INET; // host byte order
  31. their_addr.sin_family = AF_INET;
  32.  
  33. // Choose one method:
  34. // 1) my_addr.sin_port = htons(MYPORT); // short, network byte order
  35. // 2) my_addr.sin_port = htons(0); // choose an unused port at random
  36. my_addr.sin_port = htons(MYPORT); // short, network byte order
  37. their_addr.sin_port = htons(MYPORT);
  38.  
  39. // Choose one method:
  40. // 1) my_addr.sin_addr.s_addr = inet_addr("10.12.110.57");
  41. // 2) inet_aton("10.12.110.57", &(my_addr.sin_addr));
  42. // 3) my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // use my IP address
  43. my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // use my IP address
  44.  
  45. memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
  46.  
  47. if (bind(sockfd, (struct sockaddr *)&my_addr,
  48. sizeof(struct sockaddr)) == -1) {
  49. // ERROR
  50. cout << "\n-- BIND error\n";
  51. return 0;
  52. }
  53.  
  54. // ###################################################################
  55.  
  56. char Buffer[100];
  57. int BtsMvd;
  58.  
  59. cout << "Simple sockets by Matthew Cudmore...\n";
  60. cout << "Your IP: " << inet_ntoa(my_addr.sin_addr) << "\n";
  61.  
  62. GetChoice:
  63. cout << "\nEnter choice action (x = exit, s = send, a = accept): ";
  64. cin.getline(Buffer, 99);
  65.  
  66. if (Buffer[0] == 'x') {
  67. close (sockfd);
  68. return 0;
  69. } else if (Buffer[0] == 's') {
  70. cout << "Enter the IP of the receiving machine: ";
  71. cin.getline(Buffer, 99);
  72. their_addr.sin_addr.s_addr = inet_addr(Buffer);
  73. memset(&(their_addr.sin_zero), '\0', 8);
  74. cout << "Enter a message to send to the receiving machine: ";
  75. cin.getline(Buffer, 99);
  76. if ((BtsMvd = sendto(sockfd, Buffer, strlen(Buffer), 0,
  77. (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) != -1){
  78. cout << "\nMessage sent. Awaiting reply...";
  79. } else {
  80. cout << "\nMessage could not be sent.";
  81. goto GetChoice;
  82. }
  83. while (1) {
  84. if ((BtsMvd = recvfrom(sockfd, Buffer, strlen(Buffer), 0,
  85. (struct sockaddr *)&their_addr, &sl)) == -1) {
  86. // ERROR
  87. cout << "\n-- recvfrom error\n";
  88. return 0;
  89. }
  90. if (BtsMvd) {
  91. if (Buffer[BtsMvd - 1] == '*') {
  92. cout << "\nReturn received.";
  93. break;
  94. } else {
  95. cout << "\nReturn-request ignored.";
  96. }
  97. }
  98. }
  99. } else if (Buffer[0] == 'a') {
  100. cout << "Waiting for incoming return-requests...";
  101. BtsMvd = 0;
  102. while (1) {
  103. if ((BtsMvd = recvfrom(sockfd, Buffer, strlen(Buffer), 0,
  104. (struct sockaddr *)&their_addr, &sl)) == -1) {
  105. // ERROR
  106. cout << "\n-- recvfrom error\n";
  107. return 0;
  108. }
  109. if (BtsMvd) break;
  110. }
  111. cout << "\nReturn-request received from: " << inet_ntoa(their_addr.sin_addr);
  112. BtsMvd = strlen(Buffer);
  113. Buffer[BtsMvd] = '*'; Buffer[BtsMvd + 1] = '\0';
  114. if ((BtsMvd = sendto(sockfd, Buffer, strlen(Buffer), 0,
  115. (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) > 0){
  116. cout << "\nA return (" << Buffer << ") has been sent back.";
  117. } else {
  118. cout << "\nCould not return request.";
  119. }
  120. }
  121.  
  122. goto GetChoice;
  123.  
  124. return 0;
  125. }

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:
Similar Threads
Reputation Points: 20
Solved Threads: 6
Junior Poster in Training
Cudmore is offline Offline
74 posts
since Nov 2005
Nov 27th, 2005
0

Re: Please make my frist socket app work...

Here is a running code. You will have to clean it up more.
C++ Syntax (Toggle Plain Text)
  1. // My First Internet Application
  2. // By Matthew Cudmore, 2005
  3.  
  4. #include <iostream>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <unistd.h> // For gethostname
  10.  
  11. #define MYPORT 4689
  12. #define QUEMAX 10
  13. #define BUFFER_LEN 100
  14.  
  15. #ifndef SOCKET_ERROR
  16. #define SOCKET_ERROR -1
  17. #endif
  18. using namespace::std;
  19.  
  20. int main(void)
  21. {
  22. int sockfd, new_fd, sin_size;
  23. int sl = sizeof(struct sockaddr);
  24. struct sockaddr_in my_addr; // my address information
  25. struct sockaddr_in their_addr; // connector's address information
  26.  
  27. // SOCK_STREAM or SOCK_DGRAM
  28. if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR )
  29. {
  30. // ERROR
  31. cout << "\n-- SOCKET error\n";
  32. return 0;
  33. }
  34.  
  35. my_addr.sin_family = AF_INET; // host byte order
  36. their_addr.sin_family = AF_INET;
  37.  
  38. // Choose one method:
  39. // 1) my_addr.sin_port = htons(MYPORT); // short, network byte order
  40. // 2) my_addr.sin_port = htons(0); // choose an unused port at random
  41. my_addr.sin_port = htons(MYPORT); // short, network byte order
  42. their_addr.sin_port = htons(MYPORT);
  43.  
  44. // Choose one method:
  45. // 1) my_addr.sin_addr.s_addr = inet_addr("10.12.110.57");
  46. // 2) inet_aton("10.12.110.57", &(my_addr.sin_addr));
  47. // 3) my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // use my IP address
  48. my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // use my IP address
  49.  
  50. memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
  51.  
  52. if (bind(sockfd, (struct sockaddr *)&my_addr,sizeof(struct sockaddr)) == SOCKET_ERROR)
  53. {
  54. // ERROR
  55. cout << "\n-- BIND error\n";
  56. return 0;
  57. }
  58.  
  59. // ###################################################################
  60.  
  61. char Buffer[BUFFER_LEN];
  62. int BtsMvd;
  63.  
  64. cout << "Simple sockets by Matthew Cudmore...\n";
  65. cout << "Your IP: " << inet_ntoa(my_addr.sin_addr) << "\n";
  66.  
  67. GetChoice:
  68. cout << "\nEnter choice action (x = exit, s = send, a = accept): ";
  69. cin.getline(Buffer, 99);
  70.  
  71. if (Buffer[0] == 'x')
  72. {
  73. closesocket(sockfd);
  74. return 0;
  75. }
  76. else if (Buffer[0] == 's')
  77. {
  78. cout << "Enter the IP of the receiving machine: ";
  79. cin.getline(Buffer, 99);
  80. their_addr.sin_addr.s_addr = inet_addr(Buffer);
  81. memset(&(their_addr.sin_zero), '\0', 8);
  82. cout << "Enter a message to send to the receiving machine: ";
  83. cin.getline(Buffer, 99);
  84. if ((BtsMvd = sendto(sockfd, Buffer, sizeof(Buffer), 0,(struct sockaddr *)&their_addr, sizeof(struct sockaddr))) != -1)
  85. {
  86. cout << "\nMessage sent. Awaiting reply...";
  87. }
  88. else
  89. {
  90. cout << "\nMessage could not be sent.";
  91. goto GetChoice;
  92. }
  93. while (1)
  94. {
  95. if ((BtsMvd = recvfrom(sockfd, Buffer, sizeof(Buffer), 0,(struct sockaddr *)&their_addr, &sl)) == -1)
  96. {
  97. // ERROR
  98. cout << "\n-- recvfrom error\n";
  99. return 0;
  100. }
  101. if ( BtsMvd )
  102. {
  103. BtsMvd = strlen(Buffer);
  104. if (Buffer[ BtsMvd - 1 ] == '*')
  105. {
  106. cout << "\nReturn received.";
  107. break;
  108. }
  109. else
  110. {
  111. cout << Buffer<<" \nReturn-request ignored.";
  112. }
  113. }
  114. }
  115. }
  116. else if (Buffer[0] == 'a')
  117. {
  118. cout << "Waiting for incoming return-requests...";
  119. BtsMvd = 0;
  120. while (1)
  121. {
  122. if ((BtsMvd = recvfrom(sockfd, Buffer, sizeof(Buffer), 0,(struct sockaddr *)&their_addr, &sl)) == SOCKET_ERROR)
  123. {
  124. // ERROR
  125. cout << "\n-- recvfrom error\n";
  126. return 0;
  127. }
  128. if (BtsMvd)
  129. {
  130. break;
  131. }
  132. }
  133. cout << "\nReturn-request received from: " << inet_ntoa(their_addr.sin_addr);
  134.  
  135. BtsMvd = strlen(Buffer);
  136. Buffer[ BtsMvd ] = '*';
  137. Buffer[ BtsMvd + 1 ] = '\0';
  138.  
  139. their_addr.sin_family = AF_INET;
  140. their_addr.sin_port = htons(MYPORT);
  141. their_addr.sin_addr.s_addr =inet_addr( inet_ntoa(their_addr.sin_addr) );
  142. memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
  143.  
  144. if ((new_fd = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR)
  145. {
  146. // ERROR
  147. cout << "\n-- SOCKET error\n";
  148. return 0;
  149. }
  150.  
  151. if ((BtsMvd = sendto(new_fd, Buffer, sizeof(Buffer), 0,(struct sockaddr *)&their_addr, sizeof(struct sockaddr))) != SOCKET_ERROR )
  152. {
  153. cout << "\nA return (" << Buffer << ") has been sent back.";
  154. }
  155. else
  156. {
  157. cout << "\nCould not return request.";
  158. }
  159. }
  160.  
  161. goto GetChoice;
  162. return 0;
  163. }
The errors you made were not in the socket creation. This is what the Stevens Book say for bind at INADDR_ANY
Quote ...
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).
Hence you see the
C++ Syntax (Toggle Plain Text)
  1. Your IP: 0.0.0.0
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.
Moderator
Reputation Points: 572
Solved Threads: 115
Mentally Challenged Mod.
WolfPack is offline Offline
1,559 posts
since Jun 2005
Nov 27th, 2005
0

Re: Please make my frist socket app work...

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:

C++ Syntax (Toggle Plain Text)
  1. char Buffer[100];
  2. struct hostent *h; // MEEEEE
  3.  
  4. if (gethostname(Buffer, sizeof(Buffer))) {
  5. // ERROR
  6. cout << "\n-- HOST error 1\n";
  7. return 0;
  8. }
  9.  
  10. if ((h = gethostbyname(Buffer)) == 0x0) {
  11. // ERROR
  12. cout << "\n-- HOST error 2\n";
  13. return 0;
  14. }
  15.  
  16. 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:
Reputation Points: 20
Solved Threads: 6
Junior Poster in Training
Cudmore is offline Offline
74 posts
since Nov 2005
Nov 28th, 2005
0

Re: Please make my frist socket app work...

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...
Reputation Points: 29
Solved Threads: 4
Junior Poster in Training
perniciosus is offline Offline
78 posts
since Nov 2005

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: need some help please
Next Thread in C++ Forum Timeline: Searching a file for a string





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC