Working with Sockets (Client/Server)

I am trying to create a client program writtin in C++ code that should communicate with a server. I already have the server set up to listen for sockets and print out any messages sent from the client. I have having trouble on the client side when it comes to sending messages TO the server. I am very new to all of this so please dont be to hard on me. I have the following code which is primarily a set of menus for the user to choose from. What i am trying to do is have a message be sent to the server whenever the user clicks on a certain function (you can see what i mean with commented out code) but it's not working the way i want (i do get server responses but not the way i want). I know it has to do something with closing the sockets and the send() function. Please, all help is greatly appreciated .

I also provided the servers code below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
#include <iostream>
#include <string>
#include <fstream>


//this is taken straight from the it420 joke code to make sure all
//headers are referenced.  Code surrounded by these slashes
//are used to show what code was taken from the it420 client file
//////////////////////////////////////////////////////////////////
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>

#define SERVER_PORT htons(63513)
//////////////////////////////////////////////////////////////////



using namespace std;

void customerFunction(void);
void AddCust(void);
void DeleteCust(void);
void ViewCust(void);

void invoiceFunction(void);
void invoiceChange(int);

void inventoryFunction(void);
void AddInv();
void DeleteInv();
void ViewInv();
void getSocket(void);



//created a global variable so i am able to use this variable in all the functions
//again, im not sure if this is a legit way of doing it since this is usually inside
//the main
int clientSock;
//char receivedStr[1000];

int main()
{
	
	
	clientSock=socket(AF_INET,SOCK_STREAM, 0);
	
	sockaddr_in serverAddress;
	serverAddress.sin_family=AF_INET;
	serverAddress.sin_port=SERVER_PORT;
	serverAddress.sin_addr.s_addr=inet_addr("128.235.44.71");
	
	connect(clientSock, (struct sockaddr*)&serverAddress, sizeof(struct sockaddr));
	
	//main menu...prints out what to choose from on screen
	int myChoice;

	cout << string(50, '\n');
	string menuChoices[] = {"Customer Information","Inventory Information","Invoice Information","Exit"}; //Choices for the menu
	cout<<"Please choose an option"<<endl;
	for (int i=0;i<4;i++)
	{
		cout<<i+1<<"\t\t"<<menuChoices[i]<<endl; //Prints every choice in the menu
	}
	
	cout<<"(Please enter a number): ";
	cin>>myChoice; //get the choice
	
	
	//calls necessary functions depending on choice made
	switch (myChoice)
	{
		case 1:
			customerFunction(); 
			break;
		case 2:
			inventoryFunction();
			break;
		case 3:
			invoiceFunction();
			break;
		case 4:
			break; 
	}
	//close(clientSock);
	return 0;

}


//the next three functions are the functions calls straight from the main menu
//this function gets called from the main menu. Prompts user if they want to
//add delete or return to main menu. There choice then calls another function
//but i was thinking it might be possible to just leave it all in one function?
void customerFunction()
{
	
	send(clientSock, "Client currently in Customer Function", 500, 0);
	close(clientSock);
	//customer menu with choices to choose from
	cout << string(50, '\n'); //clear screen with blank spaces
	int CustChoice;
	cout<<endl;
	cout<<"What would you like to do?"<<endl;
	cout<<"1.  Add Customer"<<endl;
	cout<<"2.  Delete Customer"<<endl;
	cout<<"3.  View All Customers"<<endl;
	cout<<"4.  Main Menu"<<endl;
	cin>>CustChoice;
	
	//calls specific functions depending on choice made
	//these functions in return should send out SQL data to the server
	switch (CustChoice)
	{
		case 1:
			AddCust();
			break;
		case 2:
			DeleteCust();
			break;
		case 3:
			ViewCust();
			break;
		case 4:
			cout<<"Back to main menu"<<endl;
			//close(clientSock);
			main(); //go back to main which is the main menu
			break;
	}
	
}

//from main menu
void invoiceFunction()
{
	//this does not work
	send(clientSock, "Client currently in Invoice Function", 500, 0);
	
	cout << string(50, '\n'); //clear screen with blank spaces
	
	int InvChoice;
	
	cout<<endl;
	cout<<"What would you like to do?"<<endl;
	cout<<"1.  Create"<<endl;
	cout<<"2.  Search"<<endl;
	cout<<"3.  Main Menu"<<endl;
	cin>>InvChoice;
	
	//calls necessary functions to do action
	switch (InvChoice)
	{
		case 1:
			invoiceChange(InvChoice);
			break;
		case 2:
			invoiceChange(InvChoice);
			break;
		case 3:
			main();
			break;
	}
	
close(clientSock); 
}

//from main menu
void inventoryFunction()
{
	cout << string(50, '\n'); //clear screen with blank spaces
	
	int InvChoice;
	
	cout<<endl;
	cout<<"What would you like to do?"<<endl;
	cout<<"1.  Add"<<endl;
	cout<<"2.  Delete"<<endl;
	cout<<"3.  View"<<endl;
	cout<<"4.  Main Menu"<<endl;
	cin>>InvChoice;
	
	//calls necessary functions to do action
	switch (InvChoice)
	{
		case 1:
			AddInv();
			break;
		case 2:
			DeleteInv();
			break;
		case 3:
			ViewInv();
			break;
		case 4:
			main();
			break;
	}
	
	
}


//these remaining functions are the sub functions being called
//to send SQL data to the server
//I didnt fully code all of it yet since my main concern is getting the sockets working
void AddCust()
{
	
	cout << string(50, '\n'); //clear screen with blank spaces
	string lastName;
	string firstName;
	string StreetAddress;
	string city;
	string state;
	int zipcode;
	int phoneNumber;
	
	cout<<"Please fill out the appropriate fields:"<<endl;
	cin.ignore();
	
	cout<<"Last Name: ";
	getline(cin,lastName);
	
	cout<<"First Name: ";
	getline(cin,firstName);
	
	cout<<"Street Address: ";
	getline(cin,StreetAddress);
	
	cout<<"City: ";
	getline(cin,city);
	
	cout<<"State: ";
	getline(cin,state);
	
	cout<<"Zipcode: ";
	cin>>zipcode;
	
	cout<<"Phone Number: ";
	cin>>phoneNumber;
	
}


void DeleteCust()
{
	//getSocket();	
	//send(clientSock, "I am here to delete a customer", 500, 0);
	cout<<"chose to delete customer";
	//close(clientSock);
}

void ViewCust()
{
	cout<<"chose to view customer";	
}

void invoiceChange(int num)
{	
	if(num==1)
	{
		cout<<"Chose to Create"<<endl;
	}
	else 
	{
		cout<<"Chose to Search"<<endl;
	}	
}

//not fully developed
void AddInv()
{
}
void DeleteInv()
{
}
void ViewInv()
{
}



HERE IS THE SERVER CODE:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// This program implements a TCP Server 

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string>
#include <arpa/inet.h>

using namespace std;

/* This is port number that the server will listen to.
   This port number must be used in the client */
#define SERVER_PORT htons(63513)

int main() {
	
	char receivedStr[1000];

	/* create socket */
	int serverSock=socket(AF_INET, SOCK_STREAM, 0);

	/* Create sockaddr_in structure for the server socket.  
           INADDR_ANY means accept a connection on any of this host's IP addresses*/
	sockaddr_in serverAddr;
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = SERVER_PORT;
	serverAddr.sin_addr.s_addr = INADDR_ANY;

	/* bind (this socket, local address, address length)
           bind server socket (serverSock) to server address (serverAddr).  
           Necessary so that server can use a specific port */ 
	bind(serverSock, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr));

	// wait for a client
	/* listen (this socket, request queue length) */
	listen(serverSock,4);

	// Do forever 
	while (1 == 1) {
		
		// accept a connection request from client
		/* First, create a sockaddr_in struct to hold the address of the client.  
                   Then, create a NEW socket (called clientSock) to talk to the client and connect it to the client socket.   
                   accept (old socket, client socket address, length of client socket address)*/  
		sockaddr_in clientAddr;
		socklen_t sin_size=sizeof(struct sockaddr_in);
		int clientSock=accept(serverSock,(struct sockaddr*)&clientAddr, &sin_size);

		//receive a message from a client
		recv(clientSock, receivedStr, 500, 0);
		cout << "Server received:  " << receivedStr << endl;
		
		close(clientSock);
		}
	return 0;
	}



	

Well, for starters, it's not C++ code, it's C code that's using iostreams instead of stdio.

Secondly, why not just use SQL and bind to a C or C++ SQL client library, connect directly to your SQL database, and be done with it?

Developing a new TCP protocol is not trivial.

Thirdly, you have a buffer overrun in your send(), You have a string that is X characters in length and you are telling send() that it's 500 bytes long. Probably you have some other problems that I don't see, I only glanced briefly over it.

--Mike
thank you for the reply. I was reading up on MySQL C API (the first time im being introduced to this) so you are saying its possible to totally disregard the socket concept and go with what you mentioned about binding to a SQL client library?
Yes, whenever I have a choice, I generally choose to use MySQL, I find it to be very reliable, fast and efficient.

In any case, must SQL flavors are client/server. You simply tell your 'C' language SQL lib the IP address, login, password, and database to connect to, and they you just start writing your code to issue the queries.....piece of cake! :)

--Mike
all of the shameless plugs o.O

Sending data from server to client is exactly the same as vice-versa. Generally if you're going to have two way communication you have two options. Non-Blocking sockets, or multiple threads. If you need more info I'm glad to offer it, however a quick google search will tell you everything you need.
Topic archived. No new replies allowed.