-
Client/Server
Hi, me AGAIN!
Having trouble getting an integer sent from my client to my server...everything compiles nicely, but nothing seems to be getting recieved....
As soon as I can get some data being sent back and forth, I am well way...
Client Code
Code:
/*Socket*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
int sd;
int main(int argc,char** argv)
{
int a = 0;
sd = socket(AF_INET, SOCK_STREAM,0);
/*End of Socket*/
/*Client*/
struct sockaddr_in servaddr;
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET; //Set the domain
servaddr.sin_port = htons(atoi(argv[2])); //The port to connect to
inet_aton(argv[1],&servaddr.sin_addr); //THe IP address of the server machine.
//e.g Client 127.0.0.1 5000
connect(sd,(struct sockaddr*)&servaddr,sizeof(servaddr));
printf("Please enter the integer you wish to send ");
scanf("%d", &a);
send(sd, &a, sizeof(a), 0);
/*End of Client*/
}
//SOCK_STREAM creates a realiable two-way connection
//AF_INET specifies IPv4 Internet protocols
//s is the descriptor (sd)
//buf is the data to send (e.g a string)
//len is the length of data sent
//flags are the options(in this case can be 0).
This is my server
Code:
/*Socket*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
int sd = 0;
int main(int argc,char** argv)
{
int connfd = 0;
int listenfd = 0;
size_t clilen;
int recv_data = 0; //recieving integer data
sd = socket(AF_INET, SOCK_STREAM,0); //Creating New Socket
listenfd = sd;//Did this as listenfd has not been defined yet
/*End of Socket*/
/*Server*/
struct sockaddr_in servaddr; //Creating buffer
bzero(&servaddr,sizeof(servaddr)); //Sets all values in buffer to zero
servaddr.sin_family = AF_INET; //Sets the domain
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //Accepting connections from any machine
servaddr.sin_port = htons(atoi(argv[1])); //First argument, e.g Server 50,000 uses port 50,000
bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)); //Binds a socket to an address
listen(listenfd,10); //Accepts 10 clients to connect
int store;
//infinite for loop HERE
//used to accept connections from client
for(;;) {
struct sockaddr_in cliaddr;
connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen); //-1 if nothing is being received
store = recv(sd, &recv_data, sizeof(recv_data), 0);
if (connfd != -1)
{
printf("%d", store);
}
/*End of Client*/
}
}
//SOCK_STREAM creates a realiable two-way connection
//AF_INET specifies IPv4 Internet protocols
//listenfd is a descriptor for the servers socket(intiated when creating the socket)
I assume that when I return information back from the server, I 'send' from the server, and 'recv' at the client...
Does this mean I'd need another infinite for loop at the client, always checking wther information is being sent back or not?
Thanks
-
> store = recv(sd, &recv_data, sizeof(recv_data), 0);
> if (connfd != -1)
> printf("%d", store);
Your data is in recv_data.
How many bytes you received is in store.
If the number of bytes isn't what you expected, then you need to call recv again (and again) until you have all the bytes you expect (messages can fragment, and it's down to you to reassemble them).
-
Hi, for some completely stupid unknown reason, my server code won't printf() anything.....
to test this, I have put a printf("test") at the beginning.....and this is not being printed, yet the code is still being run and sends information to the client....this is driving me mad.....
Code:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
int main(int argc,char** argv)
{
printf("Test");
int connfd = 0;
int listenfd = 0;
size_t clilen; //this had not been initialized.
char recv_char_data[128];
listenfd = socket(AF_INET, SOCK_STREAM,0); //Creating New Socket
struct sockaddr_in servaddr; //Creating buffer
bzero(&servaddr,sizeof(servaddr)); //Sets all values in buffer to zero
servaddr.sin_family = AF_INET; //Sets the domain
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //Accepting connections from any machine
servaddr.sin_port = htons(atoi(argv[1])); //First argument, e.g Server 50,000 uses port 50,000
bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)); //Binds a socket to an address
listen(listenfd,10); //Accepts 10 clients to connect
struct sockaddr_in cliaddr, clilen_in;
clilen = sizeof(clilen_in); //This was the most important bit, this is the bit that you discovered
printf("Server Connected");
//infinite for loop HERE
//used to accept connections from client
for(;;)
{
connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen); //-1 if nothing is being received
recv(connfd, &recv_char_data, sizeof(recv_char_data), 0);
if (connfd != -1)
{
printf("%s", recv_char_data);
send(connfd, "Transaction Complete", 21, 0);
}
}
}
-
The stdout stream isn't necessarily flushed until you send a '\n', or you flush it with fflush().
Try changing toor to
Code:
printf("Test");
fflush(stdout);
-
Thanks very much :D , it's been insanely frustrating :confused: !!!
-
I'm passing an instruction to the server in the form of a single char....W would represent for example 'Withdrawl'.
Now, I don't understand what is wrong with the bolded line......I'm comparing the first value in the char array with the char 'W'....the code inside that if isn't being run.
My next problem, is that I then want to recieve another command after having entered that if statement. Say 'Ten' is passed...I've got no idea how to recieve another instruction, but from within that if statement....I thought an infinite for loop might work, constantly waiting for another instruction, but I can't even get that far....
I just need to grasp these two things and I am well away...
Code:
recv(connfd, &recv_char_data, sizeof(recv_char_data), 0);
printf("Instruction Received :: %c :: from %d\n", recv_char_data[0], connfd);
fflush(stdout);
if(recv_char_data[0] == 'W')
{
for(;;)
{
recv(connfd, &recv_char_data, sizeof(recv_char_data), 0);
}
}
-
You aren't guaranteed that 2 sends will equal 2 recvs. Both sends could very likely be in your receive data after the first recv() call.
-
I now only need to take one recieve off the user, that's on the server side. When I try and 'send' more than once from the server to the client, it doesn't work.
I'm assuming I have a problem with the 'recv' on the client side....how do I recieve more than one' send'?
(both of the 'send's aren't stored in the one 'recv' on the client side, the second one goes missing...)
-
Right, hello everyone again....I'm making some progress now...
With the 'Pushes' still left in the server, the output returned to the client is aload of gibberish....
Is there anything that anyone can see that is completely wrong with my code? I'll include my stack, server and client:
STACK :
Code:
#include<stdio.h>
#include"stack.h"
struct store{
int data_int;
char data_char;
int num;
} peeking;
stack_t* stack;
int stack_size;
void push(int d_int, char d_char, stack_t **stackptr) //Pushes integer onto the stack
{
stack_t* push_element; //Stack pointer
push_element = (stack_t*) malloc(sizeof(stack_t)); //Allocating memory
push_element->data_int = d_int;
push_element->data_char = d_char; //Data assigned
push_element->next = (*stackptr); //Next is now equal to the address [which is of type pointer ] that stackptr [pointer to a pointer] points to.
(*stackptr) = push_element; //Address stackptr points to now stores new_element
stack_size++; //Increment stack size, as integer has been pushed
}
void pop(stack_t **stackptr) //Pop integer off the stack
{
int d_int;
char d_char; //Used to store data
stack_t* pop_element; //Stack pointer
if (stack_size != 0) //If stack is not empty
{
pop_element = (*stackptr); //pop_element is now equal to the address [which is of type pointer ] that stackptr [pointer to a pointer] points to.
d_int = pop_element->data_int;
d_char = pop_element->data_char;
//Data is copied
(*stackptr) = pop_element->next; //Stackptr now points to pop_element->next.
free(pop_element); //Remove pointer after usage.
stack_size--; //Decrement stack size, as integer has been popped.
}
}
struct store peek(stack_t **stackptr, int size) //Displays all values in the stack
{
stack_t* peek_element; //Stack pointer
stack_t* store_element; //Stack pointer
int i;
int d_int;
char d_char;
store_element = (*stackptr); //Stack pointer stores address that *stackptr points to.
printf("Peeking at stack:: ");
for ( i=0; i < size; i++) //Loop untill i = stack size.
{
peek_element = (*stackptr); //Peek_element is now equal to the address [which is of type pointer ] that stackptr [pointer to a pointer] points to.
peeking.data_int = peek_element->data_int;
peeking.data_char = peek_element->data_char; //Data is copied
(*stackptr) = peek_element->next; //Stackptr now points to peek_element->next
//Prints value of data
}
return peeking; //Returns value at top of stack
printf("\n"); //New line
(*stackptr) = store_element; //*stackptr now points to store_element, restoring it's orginal value.
}
SERVER:
Code:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include"stack.h"
struct receive_data {
char command;
int int_part;
int id_part;
} recv_data;
struct send_data {
char char_data[128];
int int_data;
} s_data;
struct user {
int id;
int total;
int transaction;
stack_t *stack;
}my_user[3];
struct store{
int data_int;
char data_char;
int num;
};
int withdraw(int num, int withdrawl_cash);
int deposit(int num, int deposit_cash);
int main(int argc,char** argv)
{
int i;
int k = 0;
int connfd = 0;
int listenfd = 0;
size_t clilen; //this had not been initialized.
char send_char[128];
char trans[22] = "Transaction Completed";
listenfd = socket(AF_INET, SOCK_STREAM,0); //Creating New Socket
struct sockaddr_in servaddr; //Creating buffer
bzero(&servaddr,sizeof(servaddr)); //Sets all values in buffer to zero
servaddr.sin_family = AF_INET; //Sets the domain
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //Accepting connections from any machine
servaddr.sin_port = htons(atoi(argv[1])); //First argument, e.g Server 50,000 uses port 50,000
bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)); //Binds a socket to an address
listen(listenfd,10); //Accepts 10 clients to connect
struct sockaddr_in cliaddr, clilen_in;
clilen = sizeof(clilen_in); //This was the most important bit, this is the bit that you discovered
printf("*Server Connected*\n");
//Initializing data for testing purposes (assuming that server will constantly be running, this data would be readily avaliable to the customers)
my_user[0].id = 0000;
my_user[0].total = 10;
my_user[1].id = 1111;
my_user[1].total = 20;
my_user[2].id = 2222;
my_user[2].total = 30;
my_user[3].id = 3333;
my_user[3].total = 40;
my_user[4].id = 4444;
my_user[4].total = 0;
//infinite for loop HERE
//used to accept connections from client
for(;;)
{
connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen); //-1 if nothing is being received
if (connfd != -1)
{
recv(connfd, &recv_data, sizeof(recv_data), 0);
printf("\n\nInstruction Received :: %c ::\n", recv_data.command);
printf("Value Received :: %d ::\n", recv_data.int_part);
fflush(stdout);
if(recv_data.command == 'W')
{
for (i = 0; i < 4; i++)
{
if (my_user[i].id == recv_data.id_part)
{
k = i;
printf("\nUser Number %d", k);
my_user[k].transaction++;
push(recv_data.int_part,recv_data.command,&my_user[k].stack);
}
}
s_data.int_data = withdraw(k,recv_data.int_part);
strcpy(s_data.char_data,trans);
send(connfd, &s_data, sizeof(s_data),0);
}
else if (recv_data.command == 'D')
{
for (i = 0; i < 4; i++)
{
if (my_user[i].id == recv_data.id_part)
{
k = i;
printf("\nUser Number %d", k);
my_user[k].transaction++;
push(recv_data.int_part,recv_data.command,&my_user[k].stack);
}
}
s_data.int_data = deposit(k,recv_data.int_part);;
strcpy(s_data.char_data,trans);
send(connfd, &s_data, sizeof(s_data),0);
}
else if (recv_data.command == 'C')
{
for (i = 0; i < 4; i++)
{
if (my_user[i].id == recv_data.id_part)
{
k = i;
printf("\nUser Number %d", k);
my_user[k].transaction++;
push(recv_data.int_part,recv_data.command,&my_user[k].stack);
}
}
s_data.int_data = my_user[k].total;
strcpy(s_data.char_data,trans);
send(connfd, &s_data, sizeof(s_data),0);
}
else if(recv_data.command == 'M')
{
for (i = 0; i < 4; i++)
{
if (my_user[i].id == recv_data.id_part)
{
k = i;
printf("\nUser Number %d", k);
my_user[k].transaction++;
push(recv_data.int_part,recv_data.command,&my_user[k].stack);
}
}
struct store test[my_user[k].transaction];
for (i=my_user[k].transaction; i > 0 ; i--)
{
test[i] = peek(&my_user[k].stack, i);
}
send(connfd, &test, sizeof(test),0);
}
}
}
}
int withdraw(int num, int withdrawl_cash)
{
printf("\nBefore Withdrawl - %d",my_user[num].total);
my_user[num].total = (my_user[num].total - withdrawl_cash);
printf("\nAfter Withdrawl - %d",my_user[num].total);
return my_user[num].total;
}
int deposit(int num, int deposit_cash)
{
printf("\nBefore Deposit - %d",my_user[num].total);
my_user[num].total = (my_user[num].total + deposit_cash);
printf("\nAfter Deposit - %d",my_user[num].total);
return my_user[num].total;
}
CLIENT:
Code:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
struct send_data {
char command;
int int_part;
int id_part;
} my_data;
struct store{
int data_int;
char data_char;
int num;
}recv_mini[100];
int sd;
int main(int argc,char** argv)
{
sd = socket(AF_INET, SOCK_STREAM,0);
struct sockaddr_in servaddr;
char recv_data[128];
int recv_data_int;
int e,p,i;
char a;
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET; //Set the domain
servaddr.sin_port = htons(atoi(argv[2])); //The port to connect to
inet_aton(argv[1],&servaddr.sin_addr); //THe IP address of the server machine.
connect(sd,(struct sockaddr*)&servaddr,sizeof(servaddr));
printf("\n*Client Connected*\n");
fflush(stdout);
printf("\nPlease enter your pin number\n");
scanf("%d", &p);
my_data.id_part = p;
printf("\nWhich action would you like?\n\n Withdraw(W)\n Deposit(D)\n Check Balance(C)\n Mini Statement(M)\n Quit(Q)\n\n: ");
scanf("%s", &a);
my_data.command = a;
switch(a)
{
case 'W' : printf("\nHow much would you like to withdraw?\n\n::10:: ::20::\n::30:: ::40::\n::50:: ::100::\n::150:: ::200::\n:");
scanf("%d", &e);
my_data.int_part = e;
send(sd, &my_data, sizeof(my_data), 0);
recv(sd, &recv_data, sizeof(recv_data), 0);
printf("%s\n", recv_data);
fflush(stdout);
break;
case 'D' : printf("\nHow much would you like to deposit?\\n\n::10:: ::20::\n::30:: ::40::\n::50:: ::100::\n::150:: ::200::\n:");
scanf("%d", &e);
my_data.int_part = e;
send(sd, &my_data, sizeof(my_data), 0);
recv(sd, &recv_data, sizeof(recv_data), 0);
printf("%s\n", recv_data);
break;
case 'C' : printf("\nChecking balance...");
send(sd, &my_data, sizeof(my_data), 0);
recv(sd, &recv_data_int, sizeof(recv_data_int), 0);
printf("\nYour balance is ");
printf("%d Pounds\n", recv_data_int);
break;
case 'M' : printf("\nReceiving mini statement...");
send(sd, &my_data,sizeof(my_data),0);
recv(sd, &recv_mini,sizeof(&recv_mini) , 0);
//struct store recv_mini[sizeof(&recv_mini)];
for (i=0; i < sizeof(&recv_mini); i++)
{
printf("%c", recv_mini[i].data_char);
printf("%d", recv_mini[i].data_int);
}
break;
case 'Q' :printf("\nQuitting...\n");
break;
default : printf("\nERROR you have not entered a valid letter, please start over");
break;
}
return 0;
}
Sorry about all the code! Also thanks very much for all of your help thus far.
-
hi
i did not look your last message (too long to be read in midnight!). So, for your previous message...
Try to use fork() your application and each child would reply one request from another client. Or, you can use threads...
And two more things...You must get a warning while compiling your code that is about main, there is no return statement! And always make error checking in networking functions. Most of them return -1 on error.
-
Moved to network forum.
It would be a good idea if you worked your way through some of the sticky threads at the top of this forum.
-
would it be possible for this thread to be deleted? Or at least allow me to remove some of my code...
-
Sure, you can edit out all your posts if you want, but if the result is a meaningless thread then it will most likely be deleted for good.
It's not a good idea to make a habit of it though.
-
I won't make a habit of it, as I realise it is completely pointless...the only reason I ask is that I've put alot of code up, and I don't want others to get an easy ride but simply copying what I have put...
I can't seem to edit anything before 16/12/05.....tis why I asked really....