Need Help with my Client/Server Code

Ok, So I can successfully send and receive messages with my code, but the problem at hand is a little harder.
First the admin must start the server program and then read the current weather information for various cities from a data file and stores the information into an array of records. The user executes the client program and provides a city name to the program. The client sends that to the server, the server receives the information and obtains the current weather information for the city and sends the information back to the client. The sender code is 100% complete, and I have the base for the Receiver. Please help:

Sender Code:

01 #include <iostream> // cout, cerr, endl
02 #include <string> // string
03 #include <cstdlib> // exit()
04 #include <sys/socket.h> // socket(), sendto(), inet_aton(), struct sockaddr,
05 // AF_INET, SOCK_DGRAM
06 #include <netinet/in.h> // inet_aton(), struct sockaddr_in
07 #include <arpa/inet.h> // htons(), inet_aton()
08 #include <unistd.h> // close()
09 #include <fstream>
10
11 using namespace std;
12
13 //const unsigned int RECEIVER_PORT = 3145; // receiver port
14 const int BUFLEN = 256;
15
16
17
18 int main(int argc, char *argv[])
19 {
20 int sockfd; // socket descriptor
21 struct sockaddr_in receiver; // receiver address information
22 string city; // message, which is argv[2]
23 int bytes; // number of bytes sent to receiver
24 int port; //*** Port from Input file
25 ifstream portfile;
26 char buf[BUFLEN + 1];
27 socklen_t sockaddrlen;
28
29
30
31 if(argc != 3) {
32 cerr << "Usage: " << argv[0] << " <address> <city>" << endl;
33 exit(1);
34 }
35
36
37 portfile.open("port.dat");
38 if(!portfile) {
39
40 cout << "Error: Can't open input file" << endl;
41 return 1;
42 }
43
44 portfile >> port;
45 portfile.close();
46
47
48
49
50 // create socket
51 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
52 cerr << "Error: socket() failed" << endl;
53 exit(1);
54 }
55
56
57
58
59 // receiver address information
60 receiver.sin_family = AF_INET; // address family
61 receiver.sin_port = htons(port); // port number
62 if(inet_aton(argv[1]/*Ip Address*/, &receiver.sin_addr) == 0) { // IP address
63 cerr << "Error: inet_aton() failed" << endl;
64 exit(1);
65 }
66
67 // send message
68 city = argv[2];
69 if((bytes = sendto(sockfd, city.c_str(), city.length(), 0,
70 (struct sockaddr *)&receiver, sizeof(struct sockaddr))) == -1) {
71 cerr << "Error: sendto() failed" << endl;
72 exit(1);
73 }
74 cout << bytes << " bytes sent to " << inet_ntoa(receiver.sin_addr) << endl;
75
76 // receive message
77 sockaddrlen = sizeof(struct sockaddr);
78 if((bytes = recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr *)&receiver, &sockaddrlen)) == -1) {
79 cerr << "Error: recvfrom() failed" << endl;
80 exit(1);
81 }
82
83
84 cout << bytes << " bytes received from " << inet_ntoa(receiver.sin_addr)
85 << " (sender port# = " << ntohs(receiver.sin_port) << ")" << endl;
86 buf[bytes] = '\0';
87 city = buf;
88 cout << "city: \"" << city << "\"" << endl;
89
90
91
92 // close socket descriptor
93 if(close(sockfd) != 0) {
94 cerr << "Error: close() failed" << endl;
95 exit(1);
96 }
97
98 return 0;
99 }

The Reciever:

01 #include <iostream> // cout, cerr, endl
02 #include <string> // string
03 #include <cstdlib> // exit()
04 #include <sys/socket.h> // socket(), bind(), recvfrom(), struct sockaddr,
05 // socklen_t, AF_INET, SOCK_DGRAM
06 #include <netinet/in.h> // struct sockaddr_in
07 #include <arpa/inet.h> // htons(), ntohs()
08 #include <unistd.h> // close()
09 #include <fstream>
10 using namespace std;
11
12 const unsigned int PORT = 3145; // receiver listens on this port
13 const int BUFLEN = 256; // buffer length (size)
14
15
16 int main(int argc, char *argv[])
17 {
18 int sockfd; // socket descriptor
19 struct sockaddr_in receiver; // receiver address information
20 struct sockaddr_in sender; // sender address information
21 char buf[BUFLEN + 1]; // message buffer
22 string message; // message
23 int bytes; // number of bytes received
24 socklen_t sockaddrlen; // sizeof(struct sockaddr), used by recvfrom()
25 ifstream portfile;
26 int port;
27
28
29 portfile.open("port.dat");
30 if(!portfile) {
31 cout << "Error: Can't open input file" << endl;
32 return 1;
33 }
34
35 portfile >> port;
36 portfile.close();
37
38 // create socket
39 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
40 cerr << "Error: socket() failed" << endl;
41 exit(1);
42 }
43
44 // receiver address information
45 receiver.sin_family = AF_INET; // address family
46 receiver.sin_port = htons(port); // port number
47 receiver.sin_addr.s_addr = INADDR_ANY; // IP address
48
49 // assign receiver address to socket
50 if(bind(sockfd, (struct sockaddr *)&receiver, sizeof(struct sockaddr))
51 == -1) {
52 cerr << "Erorr: bind() failed" << endl;
53 exit(1);
54 }
55
56 cout << "Waiting for message on port " << port << "..." << endl;
57
58 // receive message
59 sockaddrlen = sizeof(struct sockaddr);
60 if((bytes = recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr *)&sender,
61 &sockaddrlen)) == -1) {
62 cerr << "Error: recvfrom() failed" << endl;
63 exit(1);
64 }
65
66 cout << bytes << " bytes received from " << inet_ntoa(sender.sin_addr)
67 << " (sender port# = " << ntohs(sender.sin_port) << ")" << endl;
68 buf[bytes] = '\0';
69 message = buf;
70 cout << "message: \"" << message << "\"" << endl;
71
72
73
74
75 // close socket descriptor
76 if(close(sockfd) != 0) {
77 cerr << "Error: close() failed" << endl;
78 exit(1);
79 }
80
81 return 0;
82 }

I have everything fixed in both codes, except for one part. Our professor didn't explain how to send the information back to the client...

So basically, I can compile both and run them. First I run the Server or Receiver code. It will say "Waiting for message on port 3145...". I then open my Client or Sender code and compile and run it. It says "Usage: ./a.out <address> <city>". I then type in "./a.out 127.0.0.1 "New York". After I send it, the Server is supposed to read the weather information for New York from an array of records (I.e Struct). Which I have created already, I just don't know how to properly execute the function to send back the information to the Client!!

Here is my new Code almost finished!!


001 #include <iostream> // cout, cerr, endl
002 #include <string> // string
003 #include <cstdlib> // exit()
004 #include <sys/socket.h> // socket(), bind(), recvfrom(), struct sockaddr,
005 // socklen_t, AF_INET, SOCK_DGRAM
006 #include <netinet/in.h> // struct sockaddr_in
007 #include <arpa/inet.h> // htons(), ntohs()
008 #include <unistd.h> // close()
009 #include <fstream>
010 using namespace std;
011
012 // const unsigned int PORT = 3145; // receiver listens on this port
013 const int BUFLEN = 256; // buffer length (size)
014
015 struct weatherType
016 {
017 string city;
018 string weather;
019 };
020
021 int main(int argc, char *argv[])
022 {
023 int sockfd; // socket descriptor
024 struct sockaddr_in receiver; // receiver address information
025 struct sockaddr_in sender; // sender address information
026 char buf[BUFLEN + 1]; // message buffer
027 string message; // message
028 int bytes; // number of bytes received
029 socklen_t sockaddrlen; // sizeof(struct sockaddr), used by recvfrom()
030 ifstream portfile;
031 int port;
032 int i = 0;
033 ifstream infile;
034 weatherType info[100];
035
036 infile.open("weather1.dat");
037 if(!infile) {
038 cout << "Error: can't open weather file" << endl;
039 return 1;
040 }
041
042 while(!infile.eof())
043 {
044 infile >> info[i].city >> info[i].weather;
045 infile.ignore(2, '\n');
046 i++;
047 }
048
049 infile.close();
050
051 portfile.open("port.dat");
052 if(!portfile) {
053 cout << "Error: Can't open input file" << endl;
054 return 1;
055 }
056
057 portfile >> port;
058 portfile.close();
059
060 // create socket
061 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
062 cerr << "Error: socket() failed" << endl;
063 exit(1);
064 }
065
066 // receiver address information
067 receiver.sin_family = AF_INET; // address family
068 receiver.sin_port = htons(port); // port number
069 receiver.sin_addr.s_addr = INADDR_ANY; // IP address
070
071 // assign receiver address to socket
072 if(bind(sockfd, (struct sockaddr *)&receiver, sizeof(struct sockaddr))
073 == -1) {
074 cerr << "Erorr: bind() failed" << endl;
075 exit(1);
076 }
077
078 cout << "Waiting for message on port " << port << "..." << endl;
079
080 // receive message
081 sockaddrlen = sizeof(struct sockaddr);
082 if((bytes = recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr *)&sender,
083 &sockaddrlen)) == -1) {
084 cerr << "Error: recvfrom() failed" << endl;
085 exit(1);
086 }
087 cout << bytes << " bytes received from " << inet_ntoa(sender.sin_addr)
088 << " (sender port# = " << ntohs(sender.sin_port) << ")" << endl;
089 buf[bytes] = '\0';
090 message = buf;
091 cout << "message: \"" << message << "\"" << endl;
092
093 // Send Message Back **************************************************************************
094 for(i = 0; i < 100; ++i) {
095
096 if((bytes = sendto(sockfd, message.c_str(), message.length(), 0, (struct sockaddr *)&receiver, sizeof(struct sockaddr))) == -1) {
097 cerr << "Error: sendto() failed" << endl;
098 exit(1);
099 }
100 cout << bytes << " bytes sent to " << inet_ntoa(sender.sin_addr) << endl;
101 cout << info[i].city << " " << info[i].weather << endl;
102 }
103
104 *****************************************************************************************************
105
106 // close socket descriptor
107 if(close(sockfd) != 0) {
108 cerr << "Error: close() failed" << endl;
109 exit(1);
110 }
111
112 return 0;
113 }

The Starred Out part is where the Send Back function is supposed to be, I know it's wrong but I just don't know how to properly do it.
Where shall I begin? Ok, here we go.

1. Welcome to the forum.

2. Please use the code format tag from the pallet on the right to format your code.

3. You should think of your program as you've described it, a client/server app. Don't use the term sender/receiver. The server will listen for requests and serve them. The client make requests and receives answers.

4. The first thing to focus on is the weather data structures. Have you looked at all at how you might do this? As the server will be asked to look up by city, you must provide a function that looks up the data by city and returns something.

I can see the server use a variable info, but I can't see its definition.

5. There are issues with the comms, but let's get the basics right first.
Topic archived. No new replies allowed.