Am working on a project where it is a communication between server client. Server opens a specific file and stores the message from the client in a buffer using while(1) for repeated communication. All am trying is manage the message like, when client sends this message : AT+REG1=5 , i want to split it ("=") in order to determine operations and values : operation = AT+REG1 And value is 5. In my code i have a struct with informations for "operation" and "value". I use strtok function to split message but it doesnt work right and i dont know why , for example i send through client AT+REG1=5 and when i split the message like :
token=strtok("AT+REG1=5","="); // points to AT+REG1
value=strtok(NULL,"="); // points to the value but returns null
It returns that value is (null) despite that it must return "5".
My build for that is :
typedef enum operation{
insert,
read_reg,
info
}Operation;
typedef struct request{
Operation operation;
int ID;
int **regs;
}Request;
Function that handles the split of message:
Request *parse_request(char *buffer){
char *token=NULL,*value=NULL;
Request *rep=NULL;
rep=(Request*)malloc(sizeof(Request));
token=strtok(buffer,"=");
printf("token:%s\n",token);
value=strtok(NULL," ");
printf("value=%s\n",value);
return rep;
}
And now the main loop where i call this function after receiving the message :
char buffer[SIZE];
while(1){
//Clean buffer
memset(buffer,0,SIZE);
FD_ZERO(&readfd);
FD_SET(fd,&readfd);
timeout.tv_sec=100;
timeout.tv_usec=0;
status=select(40,&readfd,NULL,NULL,&timeout);
if(status==0){
printf("Cannot receive data from client\n");
printf("\tTime Out\n");
exit(1);
}
read_num=read(fd,buffer,sizeof(buffer));
if(read_num<0) perror("Error in reading file descriptor\n");
if(read_num>0){
request=parse_request(buffer);
break;
}
}
The main problem here is that strtok returns null in at value parameter despite that the message is AT+REG1=5 and it must show "5".
Related
So I made a simple server-client program that can communicate with each other using fifo file (msgfifo).
My question is: When I type a message which includes a space, the receiver process runs several times with number of words.
That's not I expected, as I expected to print it out as a whole sentence, but it doesn't, and I want to know why.
When I type a something to send, process send SIGUSR1 signal to another.
/* receive msg part */
/* added this using sigset(SIGUSR1, receiveSIGUSR1) */
void receiveSIGUSR1()
{
char* msg = "\nIncoming Message from client...";
char* msg2 = "\nClient : ";
char buf[max_of_msg];
int fd;
write(1, msg, strlen(msg)+1);
fflush(stdin);
if( (fd = open("./msgpipe", O_RDONLY)) < 0)
{ perror("open"); exit(1); }
read(fd, buf, max_of_msg);
close(fd);
write(1, msg2, strlen(msg2)+1);
write(1, buf, strlen(buf)+1);
flag = 0;
}
/*send msg part*/
while(1)
{
flag = -1;
printf("\nType what u want to send : ");
scanf(" %s", msg);
if(flag == 0) continue;
printf("msgtaken\n");
fflush(stdin);
if( (fd = open("./msgpipe", O_RDWR)) < 0)
{ perror("exit"); exit(1); }
kill(clpid, 30);
sleep(2);
printf("Send message to Client..\n");
write(fd, msg, max_of_msg);
printf("Message Sent...\n");
}
Expected:
Client : Hello Server this is client
Actual:
/* server */
Incoming Message from client... Hello Incoming Message
from client... this Incoming Message from client... is
Incoming Message from client... client Type what u
want to send :
/client/
Type what u want to send : Hello Server This is client
msgtaken Send message to server.. Message sent
Type what u want to send : msgtaken Send message to server..
Message sent Type what u want to send : msgtaken Send
message to server.. Message sent Type what u want to send
: msgtaken Send message to server.. Message sent Type
what u want to send : msgtaken Send message to server..
Message sent
Type what u want to send :
That's because this is how it takes input:
scanf(" %s", msg);
Let's have a look at the documentation of scanf (emphasis mine):
s: Any number of non-whitespace characters, stopping at the first
whitespace character found. A terminating null character is
automatically added at the end of the stored sequence.
That's why it stops after Hello when you send Hello Server this is client. Also note the space in " %s", this means that it will also ignore any whitespace at the start of the input. So when it reads the Server on the next run through the loop, this makes it ignore the space between Hello and Server. As a result, it goes through the loop five times, and the messages each time are Hello, Server, this, is and client.
Instead, you could use getline:
char *message = NULL;
size_t length;
getline(&message, &length, stdin);
// use message
free(message);
A little side note: to make your scanf call more safe, you can specify a maximum size for the string input:
scanf(" %99s", msg);
Per example, this would mean that only 99 char can be read in, plus a null terminator, for a buffer size of 100. This way you can avoid undefined behavior that would occur if the user would enter a string that is too big for your buffer.
How do I extract the actual data (in a form of human readable string, character, an integer etc.) from an incoming stream on a socket in C? The point of this is to be able to act on the contents of the incoming message.
struct netconn *client = NULL;
struct netconn *nc = netconn_new(NETCONN_TCP);
netconn_bind(nc, IP_ADDR_ANY, 8569);
netconn_listen(nc);
while (1) {
err_t err = netconn_accept(nc, &client);
if (err == ERR_OK) {
struct netbuf *nb;
if ((err = netconn_recv(client, &nb)) == ERR_OK) {
/* INTERPRETE INCOMING DATA HERE?? */
}
netbuf_delete(nb);
}
netconn_close(client);
netconn_delete(client);
}
The client connects and sends, say 'testing123' string. How do I go about interpreting this string on the 'server' side?
The point of this exercise is to be able to trigger desired behaviour on the receiving end with the use of appropriate 'command' sent across the local network to WLAN-attached ESP8266 microcontroller.
Ps. I realize it's probably very primitive mechanism so I would appreciate some feedback regarding this matter. Any thoughts/ideas/suggestions greatly appreciated.
As your server can't know what and how the data is being send you need to specify a common message or some kind of seperator between words if you choose to use strings.
For example you could use a | as a seperator so that you would input the following on your client: testing|123
On your server you would now need to search for the | seperator and divide the incoming data so you have a string "testing" and a int "123".
As another aproach you could define yourself a interface based on numbers with the help of a struct.
For example:
typedef struct
{
int cmd;
int subCmd;
} cmdStruct;
In this you would need to deserialize the incoming bytes and parse them to the command structure and act upon the received command. This would include that you send the command accordingly.
Trivial excercise as it turns out. The netbuf structure have 'placeholders' for the contents of incoming data and it's lenght;
netbuf_data(nb, &data, &len);
In my case;
/* INTERPRETE INCOMING DATA HERE?? */
void *data;
u16_t len;
netbuf_data(nb, &data, &len);
char * theData = data;
printf("%s\n", theData);
prints the incoming string on-screen.
I am writing a program which uses socket programming in c.
In this program a client and server keep transmitting and receiving data.
When I send and receive integers over the socket using this kind of code
//in the program sending data
int data;
len= send(s,(char *)&(data),sizeof(data),0);
//in the program receiving data
int num;
len = recv(s,&num, sizeof(num) , 0);
The above code is working fine and I am able to transmit and receive numbers.
In one case I am trying to send a structure of the form
struct sample{
int num;
char chain[10*hops+10];
};
//in the program sending data
struct sample s1;
len= send(s,(char *)&(s1),sizeof(s1),0);
//in the program receiving data
struct sample s2;
len = recv(s,&s2, sizeof(s2) , 0);
In the example where I am trying to send and receive structure it is not working. How to send and receive the struct successfully ?
Note:
1) Hops is a pre defined variable.The value of hops is same in both the programs.
2) By not working I meant : when I receive the struct and print the value in the the num. It is printing not the same value but zero!
if you are trying to send the struct you must use serialization and deserialization, read about that, you can start with :
Serialization issues while sending struct over socket
I am trying to send an array of strings over a socket and receive it on the other end.
Here is my client side ( side sending the data ) :
char* client_hello[] =
{
"Type client_hello",
"Version SSLv3.0",
"Session ID 1",
"Random 1as2#3%$h&KF(*)JAGG&(#H%A$D#J*##",
"Cipher-Suites TLS_RSA_WITH_RC4_128_SHA",
"Compression null(0)"
};
SendBytes = send(sock, client_hello, 6, 0);
This is my Server side ( side receiving the data ):
int inMsgLen = recvfrom(clntSock, inMsg, 1024, 0,(struct sockaddr *)&clntAddr, (socklen_t*)&clntAddrLen);
if (inMsgLen < 0) {
//printf("Error in recvfrom() errno=%d\n", errno);
continue;//exit(1);
}else if (inMsgLen > 1024) {
printf("Received message too long (size=%d)\n", inMsgLen);
exit(1);
}else{
printf("Received Message: %s\n", inMsg);
}
inMsg is declared as char inMsg[1024];
This is what the output is on the server side :
Received Message: +?
What am I doing wrong ? How can I send/receive the entire client_hello array ?
I am trying to send an array of strings over a socket and receive it on the other end.
But the code is sending the first six bytes of an array of char* (as mentioned by WhozCraig in a comment to the question):
SendBytes = send(sock, client_hello, 6, 0);
the receiving side is reading the pointer addresses and treating them as strings, hence the junk.
To correct, send each string in turn but you will need to create a protocol that defines the beginning and end of a string as the bytes are written and read from sockets as streams, not some notion of message. For example, prefixing each string with its length (a sequence of digits terminated by a new-line character would be one simple option) followed by the actual string:
18\nSession ID 124\nCompression null(0)0\n
The receiving end would read to the new-line character, convert what was read to an int, allocate a buffer to contain the string (remembering space for the null terminator) and then read that number of char from the socket. A length of zero could be used to terminate the transfer of the list of strings.
Note that a call to send() may result in only a part of the requested data being sent. The code needs to cater for this by keeping track of the number of bytes send so far and indexing into the buffer being sent.
If you try to make a loop, using "for" to send... maybe is possible to server understand. Making client_hello[i], line by line..
The situation: I am creating a server daemon in c that accepts numerous simultaneous connections, and the clients will be sending data to the server. I currently have each client connection being spawned into a new thread.
The problem: if a client sends numerous lines of content very quickly (eg, 10 lines of data in less than a second), the server will see the first two lines, but not the rest.
The question: How can I "queue" the data coming in from the clients (the recv command in c)? Is this something that select or poll would be needed for? Basically, I want to make sure any client can send large amounts of data very quickly without having to worry about any content being dropped. How can this be achieved?
Sample Code: (note: the below code has obviously been heavily modified, esp. by removing error checking. I tried to modify my code so as to make the problem/solution clear without getting bogged down in semantics of irrelevant parts. Please don't get caught up with any non-standard or missing elements here)
//this function handles the threads
void *ThreadedFunction(void *arg) {
// do some stuff, like: pull vars out of mystruct
int nbytes;
char buf[256];
while(1) {
if((nbytes=recv(conid, buf, sizeof buf, 0)) <= 0) {
//handle break in connection
} else {
//for this example, just print out data from client to make my point
buf[nbytes] = 0;
printf("%s\n",buf);
}
}
}
//main just sets up the connections and creates threads
int main(int argc. char *argv[])
{
// bind(), listen(), etc... blah blah blah
while(1) {
conid = accept(...); //get a connection
// ... build mystruct to pass vars to threaded function ...
pthread_t p;
pthread_create(&p,NULL,ThreadedFunction,&mystruct); //create new thread
}
}
You don't need to "queue" the data coming in from the clients.
Because TCP do that for you. Flow control of TCP even slows down clients, if the server is too slow to make space to TCP receiving buffer.
So, probably there is bug in the code of server or client. Maybe client sends '\0' in the end of each line. In that case, the following code would not print all lines:
if((nbytes=recv(conid, buf, sizeof buf, 0)) <= 0) {
//handle break in connection
} else {
//for this example, just print out data from client to make my point
buf[nbytes] = 0;
printf("%s\n",buf);
}
It is even expected that the 2nd line is the last line what you see, if client sends '\0' at the end of each line.
For example:
If client sends the following lines:
"abc\n\0"
"def\n\0"
"ghi\n\0"
TCP will usually send those by using two packets, that contains following:
"abc\n\0"
"def\n\0ghi\n\0"
Server usually needs 2 recv calls to receive the incoming data.
So your server will use 2 print calls:
printf("%s\n", "abc\n\0\0");
printf("%s\n", "def\n\0ghi\n\0\0");
And the result output is:
abc
def