Can anybody give me a hand trying to implement the following server and client?:
The server:
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
int main(void) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in serv_addr = { 0 };
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(1234);
bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
listen(sock, 128);
struct sockaddr_in cli_addr = { 0 };
socklen_t cli_addrlen = sizeof(cli_addr);
int acc_sock = accept(sock, (struct sockaddr *)&cli_addr, &cli_addrlen);
printf("[+] Connected \n");
char buf[1024];
ssize_t nread;
memset(buf, 0, sizeof(buf));
int a;
while (1) {
nread = read(0, buf, 1024);
write(acc_sock, buf, nread);
memset(buf, 0, sizeof(buf));
while ((read(acc_sock, buf, 1024)) != 0) {
printf("%s", buf);
memset(buf, 0, sizeof(buf));
}
}
}
All the servers does is scanning a command from stdin and send it to the client via sockets. Then scans the client response and prints it out to stdout.
The client:
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[]) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in serv = { 0 };
char buf[1024];
char command[1024];
memset(buf, 0, sizeof(buf));
memset(command, 0, sizeof(command));
int nread;
FILE *in;
extern FILE *popen();
serv.sin_family = AF_INET;
serv.sin_port = htons(atoi(argv[1]));
serv.sin_addr.s_addr = inet_addr("127.0.0.1");
int a;
connect(sock, (struct sockaddr*)&serv, sizeof(serv));
while (1) {
nread = read(sock, buf, 1024);
in = popen(buf, "r");
while ((fgets(command, sizeof(command), in)) != NULL) {;
write(sock, command, sizeof(command));
}
memset(buf, 0, sizeof(buf));
}
return 0;
}
Essentially the client receives the command scanned by the server, executes it using popen(), and sends the contents of the command line by line until NULL.
The problem is that the code suddenly stops working just after the first command. the transmission of the command and the command's output is satisfactory, however after printing the output of the first command the program just stops working. I think is a problem with fgets(), however I could be wrong. Is there any solutions for this problem?
Caveat: This may [or may not] fit your needs because I reversed the sense of the client and server loops in the corrected code below. As I had mentioned in my comment above:
The normal orientation for an app like this is that a client connects to a server and the client feeds the commands [read from stdin] to the server [which does popen] and feeds back the results. That's how ssh works. Your orientation is reversed. What you've got is you fire sshd and wait for ssh to connect and then sshd sends commands to ssh. In other words, the loops in the respective sides should be switched.
Reversing this was the only way things made sense to me. If the reversal doesn't work [well] for your desired use case, the code below may still give you some ideas.
I solved the hang problem by introducing the concept of a flag character to denote end-of-output. I borrowed this concept from the PPP [point-to-point] protocol over RS-232.
The flag character is just a given value (e.g. 0x10) that is not likely to be part of normal data. Since your data is most likely ascii or utf-8, any [unused] chars in the range 0x00-0x1F may be used (i.e. don't use tab, cr, newline, etc).
If you need to transmit the flag character (i.e. your data has to be the full binary range 0x00-0xFF), I've included some packet encode/decode routines that implement the escape codes used in PPP above. I've coded them, but did not actually hook them in. In this case, the flag [and escape] chars can be any binary value [usually 0xFF and 0xFE respectively].
For simplicity, I combined both sides into a single .c file. Invoke the server with -s [first].
Anyway, here's the tested code [please pardon the gratuitous style cleanup]:
// inetpair/inetpair -- server/client communication
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef unsigned char byte;
#define BUFMAX 1024
int port = 1234;
int opt_svr;
int opt_debug;
#define FLAG 0x10
#define ESC 0x11
#define ESC_FLAG 0x01
#define ESC_ESC 0x02
#define dbgprt(_fmt...) \
do { \
if (opt_debug) \
printf(_fmt); \
} while (0)
// client
int
client(void)
{
int sock;
struct sockaddr_in serv = { 0 };
char *cp;
char buf[BUFMAX + 1];
int nread;
int flag;
int exitflg;
sock = socket(AF_INET, SOCK_STREAM, 0);
serv.sin_family = AF_INET;
serv.sin_port = htons(port);
serv.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(sock, (struct sockaddr *) &serv, sizeof(serv));
while (1) {
cp = fgets(buf,BUFMAX,stdin);
if (cp == NULL)
break;
exitflg = (strcmp(buf,"exit\n") == 0);
// send the command
nread = strlen(buf);
write(sock, buf, nread);
if (exitflg)
break;
while (1) {
dbgprt("client: PREREAD\n");
nread = read(sock, buf, 1024);
dbgprt("client: POSTREAD nread=%d\n",nread);
if (nread <= 0)
break;
cp = memchr(buf,FLAG,nread);
flag = (cp != NULL);
if (flag)
nread = cp - buf;
write(1,buf,nread);
if (flag)
break;
}
}
close(sock);
return 0;
}
// server
int
server(void)
{
struct sockaddr_in serv_addr = { 0 };
int sock;
int acc_sock;
char buf[BUFMAX + 1];
char command[BUFMAX + 1];
ssize_t nread;
FILE *pin;
FILE *xfin;
char *cp;
struct sockaddr_in cli_addr = { 0 };
opt_debug = ! opt_debug;
dbgprt("[+] Starting\n");
sock = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
listen(sock, 128);
while (1) {
socklen_t cli_addrlen = sizeof(cli_addr);
dbgprt("[+] Waiting for connection\n");
acc_sock = accept(sock,(struct sockaddr *)&cli_addr,&cli_addrlen);
dbgprt("[+] Connected\n");
xfin = fdopen(acc_sock,"r");
while (1) {
dbgprt("[+] Waiting for command\n");
cp = fgets(buf,BUFMAX,xfin);
if (cp == NULL)
break;
cp = strchr(buf,'\n');
if (cp != NULL)
*cp = 0;
dbgprt("[+] Command '%s'\n",buf);
if (strcmp(buf,"exit") == 0)
break;
pin = popen(buf, "r");
while (1) {
cp = fgets(command, BUFMAX, pin);
if (cp == NULL)
break;
nread = strlen(command);
write(acc_sock, command, nread);
}
pclose(pin);
command[0] = FLAG;
write(acc_sock,command,1);
}
fclose(xfin);
close(acc_sock);
dbgprt("[+] Disconnect\n");
}
}
// packet_encode -- encode packet
// RETURNS: (outlen << 1)
int
packet_encode(void *dst,const void *src,int srclen)
{
const byte *sp = src;
byte *dp = dst;
const byte *ep;
byte chr;
int dstlen;
// encode packet in manner similar to PPP (point-to-point) protocol does
// over RS-232 line
ep = sp + srclen;
for (; sp < ep; ++sp) {
chr = *sp;
switch (chr) {
case FLAG:
*dp++ = ESC;
*dp++ = ESC_FLAG;
break;
case ESC:
*dp++ = ESC;
*dp++ = ESC_ESC;
break;
default:
*dp++ = chr;
break;
}
}
dstlen = dp - (byte *) dst;
dstlen <<= 1;
return dstlen;
}
// packet_decode -- decode packet
// RETURNS: (outlen << 1) | flag
int
packet_decode(void *dst,const void *src,int srclen)
{
const byte *sp = src;
byte *dp = dst;
const byte *ep;
byte chr;
int flag;
int dstlen;
// decode packet in manner similar to PPP (point-to-point) protocol does
// over RS-232 line
ep = sp + srclen;
flag = 0;
while (sp < ep) {
chr = *sp++;
flag = (chr == FLAG);
if (flag)
break;
switch (chr) {
case ESC:
chr = *sp++;
switch (chr) {
case ESC_FLAG:
*dp++ = FLAG;
break;
case ESC_ESC:
*dp++ = ESC;
break;
}
break;
default:
*dp++ = chr;
break;
}
}
dstlen = dp - (byte *) dst;
dstlen <<= 1;
if (flag)
dstlen |= 0x01;
return dstlen;
}
int
main(int argc, char **argv)
{
char *cp;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (*cp != '-')
break;
switch (cp[1]) {
case 'd':
opt_debug = 1;
break;
case 'P':
port = atoi(cp + 2);
break;
case 's':
opt_svr = 1;
break;
}
}
if (opt_svr)
server();
else
client();
return 0;
}
The client never closes sock. Therefore the server's loop
while ((read(acc_sock, buf, 1024)) != 0) {
printf("%s", buf);
memset(buf, 0, sizeof(buf));
}
never terminates. You need some mechanism to inform server that all the command's output has been sent. Maybe something similar to HTTP chunked transfer encoding.
Related
I've got a simple client/server application. The user writes strings in the console. When he pushes enter string is sent. I can transfer one line correctly, but after it substitutes the first letter of first sent word to each next. For example, if a user sends "Hello", the server will get "Hello", but after, if I send "Hello" again, the server will get "HHello". If I try to clear buffer at the client-side after sending it, it never sends something again.
Server code:
// Server side C/C++ program to demonstrate Socket programming
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 57174
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
char buffer[1024];
bzero(buffer, sizeof(buffer));
int step = 0;
while(1){
valread = read( new_socket , buffer, 1024);
if(valread == 0)
break;
printf("%s", buffer );
printf("\n");
bzero(buffer, sizeof(buffer));
};
return 0;
}
Client code:
// Client side C/C++ program to demonstrate Socket programming
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 57174
int main(int argc, char const *argv[])
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(atoi(argv[2]));
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
// char buffer[1024] = {0};
unsigned int N = 10, delta=10, i = 0;
char* buf = (char*) malloc (sizeof(char)*N);
while (1) {
buf[i] = getchar();
if(buf[i] == 27)
break;
if(buf[i] == 10){
send(sock , buf , strlen(buf) , 0 );
// bzero(buf, sizeof(buf));
N = 10;
buf = (char*) realloc (buf, sizeof(char)*N);
i = 0;
}
if (++i >= N) {
N += delta;
buf = (char*) realloc (buf, sizeof(char)*N);
}
}
return 0;
}
if a user sends "Hello", the server will get "Hello", but after, if I send "Hello" again, the server will get "HHello"
This is because you missed an else in your client, in
if(buf[i] == 10){
send(sock , buf , strlen(buf) , 0 );
// bzero(buf, sizeof(buf));
N = 10;
buf = (char*) realloc (buf, sizeof(char)*N);
i = 0;
}
if (++i >= N) {
N += delta;
buf = (char*) realloc (buf, sizeof(char)*N);
}
you need to replace
if (++i >= N) {
by
else if (++i >= N) {
else after you sent you buffer and set i to 0 you increment it, and you will memorize the next char at the index 1, the character at the index 0 is still present and you will send it again and again
You also have a problem in your client at
send(sock , buf , strlen(buf) , 0 );
because you do not put a null character in buff needed by strlen to return the expected value, so the behavior is undefined. In fact you do not need strlen, just do
send(sock , buf , i , 0 );
supposing you do not want to send the \n
On your server side
char buffer[1024];
...
valread = read( new_socket , buffer, 1024);
if(valread == 0)
break;
printf("%s", buffer );
you fill each time buffer with null characters but in case you read 1024 characters there is no null character in your buffer and printf will go out of the buffer with an undefined behavior
warning read returns -1 on error, valread == 0 is wrong
remove all your bzero an just do
char buffer[1024];
...
while ((valread = read(new_socket, buffer, sizeof(buffer)-1)) > 0) {
buffer[valread ] = 0;
printf("%s", buffer);
}
notice I used sizeof(buffer) rather than 1024, that allows to be sure to have the right size even you resize buffer
Other remarks for the client :
the variable hello is useless
by definition sizeof(char) values 1, so sizeof(char)*N can be replaced by N everywhere
do not compare the read char with the literal 10 and 27, compare with '\n' and '\e'
you do not manage the EOF in input, for that you need to save the read char in an int rather than a char (like buf[i] is) to compare it with EOF
In the server the variable step is useless
Out of that you use SOCK_STREAM so your socket is a stream (tcp not udp), that means you cannot suppose the size of the data you read each time you call read, I mean if the client sent N bytes that does not mean the server will read N bytes on the corresponding read (if I can say 'corresponding' because there is no correspondence ;-) ).
Supposing the other problems are fixed if you input azeqsd\n you send azeqsd but may be on the server side you will read azeq so print azeq\n and on the next loop you will read sd and print sd\n.
It is also possible the server read a partial or full concatenation of several buffers sent separably by the client.
Do you want that behavior ? if no you need to send the size before each buffer to know how much to read even on several times to constitute the full sent buffer (an other advantage is you no not read byte per
I am trying to implement basic UDP multicast client and server on Linux. The server, based on a message sent by the client, is supposed to reply with system parameters (kinda like SNMP). Right now, I am testing with a single server. After running client and server on different terminals, I send a 3 character request to the server, but it appears that server is not able to proceed, and just stays suspended there, waiting for client. The codes are given here:
Client:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
char* createheader(int , int , int , char , int );
#define PORT 15002
#define MAXLINE 10000
char* MULTICAST = "224.0.0.3";
char* myIP = "127.0.0.1";
// Driver code
int main(int argc, char *argv[])
{
char buffer[10000];
char message[10000];
char *msg;
int sockfd, n;
char c = '0';
int req1, req2, req3;
int ctr = 0;
int prev = 0, curr = 0;
char tp = 'Q';
int seq = 0, len;
int yes = 1;
short int resendflag = 0;
struct timeval time1, time2, tv={2,0}; // structures that can take time in seconds and micro seconds.
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_addr.s_addr = inet_addr(MULTICAST);
servaddr.sin_port = htons(PORT);
servaddr.sin_family = AF_INET;
struct in_addr interface_addr;
interface_addr.s_addr = inet_addr(myIP);
// create datagram socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (int*) &yes, sizeof(yes));
if (sockfd < 0) {
perror("Error: socket");
exit(1);
}
/*if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
printf("\n Error : Connect Failed \n");
exit(0);
}*/
setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&tv,sizeof(struct timeval));
//u_char loop;
//setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
//Create Tx Header
while(1)
{
prev = seq;
seq++;
printf("\nEnter the 3 request characters, each followed by newline\n");
scanf("%d%d%d", &req1, &req2, &req3);
msg = createheader(req1, req2, req3, tp, seq);
while(c!='\0')
{
c = *(msg+ctr);
//puts(&c);
message[ctr] = c;
ctr++;
}
//printf("\nsize of %d",sizeof(c));
c = '0';
ctr = 0;
//msg = NULL;
// connect to server
// request to send datagram
// connect stores the peers IP and port
sendto(sockfd, message, sizeof(message), 0, (struct sockaddr*)&servaddr, sizeof(servaddr));
puts(message);
// waiting for response
n = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&servaddr, &len);
Portion after this is specific to my application: may be ignored unless you want to test it out.
curr = buffer[4]-'0' + (buffer[5]-'0')*256 + (buffer[6]-'0')*65536 + (buffer[7]-'0')*65536*256;
if (prev == curr || n == -1)
{
resendflag = 1;
while(resendflag)
{
printf("No Response Recieved. Resending...\n");
sendto(sockfd, message, strlen(message), 0, (struct sockaddr*)&servaddr, sizeof(servaddr));
n = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)NULL, NULL);
curr = buffer[4]-'0' + (buffer[5]-'0')*256 + (buffer[6]-'0')*65536 + (buffer[7]-'0')*65536*256;
if (prev == curr || n == -1)
{
resendflag = 1;
}
else
{
resendflag = 0;
puts(buffer+12);
}
sleep(1);
}
}
else
puts(buffer+12);
//tp = 'A';
//msg = createheader(req1, req2, req3, tp, seq);
// close the descriptor
}
close(sockfd);
}
char* createheader(int req1, int req2, int req3, char tp, int seq)
{
static char msg1[1000];
int len;
//char req;
msg1[0] = 'A';
msg1[1] = tp;
msg1[3] = '0';
msg1[4] = seq%256+'0';
msg1[5] = (seq/256)%256+'0';
msg1[6] = (seq/65536)%256+'0';
msg1[7] = (seq/(65536*256))%256+'0';
msg1[8] = req1+'0';
msg1[9] = req2+'0';
msg1[10] = req3+'0';
msg1[12] = '\0';
len = strlen(msg1);
msg1[2] = len +'0';
return msg1;
}
And this is the server:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <time.h>
#define PORT 15002
#define MAXLINE 10000
char* MULTICAST = "224.0.0.3";
char* myIP = "127.0.0.2";
char* createheader(int , int , int , char , int , int);
char* sysfunc(int , int , int);
// Driver code
int main(int argc, char *argv[])
{
setbuf(stdout, NULL);
printf("lololol5"); //Just some indicators to see the progress
char buffer[10000];
char *message = "Hello Client";
char msg[10000];
char *msg1;
char tp = 'R';
int yes = 1;
int listenfd, len, l=0, seq = 0, req1, req2, req3, i, curr = 0, exc = 0;
const char* syscl= NULL;
int drop;
srand(time(NULL));
FILE* fp;
struct sockaddr_in servaddr, cliaddr;
bzero(&servaddr, sizeof(servaddr));
printf("lololol4");
// Create a UDP Socket
listenfd = socket(AF_INET, SOCK_DGRAM, 0);
if (listenfd < 0) {
perror("socket");
exit(1);
}
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (int*)&yes, sizeof(yes))<0)
{
perror("socket");
exit(1);
}
printf("lololol3");
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
servaddr.sin_family = AF_INET;
char *ip = inet_ntoa(servaddr.sin_addr);
printf("\nip is %s\n", ip);
// bind server address to socket descriptor
if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
perror("bind");
exit(1);
}
printf("lololol2");
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST);
mreq.imr_interface.s_addr = inet_addr(myIP);
char *ip1 = inet_ntoa(mreq.imr_multiaddr);
printf("\nmulip is %s\n", ip1);
if (setsockopt(listenfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mreq, sizeof(mreq)) < 0)
{
perror("setsockopt");
return 1;
}
while(1)
{
//receive the datagram
len = sizeof(cliaddr);
int n = recvfrom(listenfd, (char*) buffer, sizeof(buffer), 0, (struct sockaddr*)&cliaddr, &len); //receive message from client
As before, application specific portion.
printf("\nHi\n");
puts(buffer); //display message
printf("\n");
curr = buffer[4]-'0' + (buffer[5]-'0')*256 + (buffer[6]-'0')*65536 + (buffer[7]-'0')*65536*256;//acquire client seq. no
req1 = buffer[8]; req2 = buffer[9]; req3 = buffer[10];//extract request bytes
syscl = sysfunc(req1-48, req2-48, req3-48); //Function call to get system corresponding system command string
l = 12; //After 12 bytes of header
puts(syscl);
if (strcmp(syscl, "\nInvalid Command...\n\0"))
{
system(syscl); //The system call with the string gotten
fp = fopen("sysstat.txt","r"); //Open the file where system output is written
while(!feof(fp))
{
msg[l] = fgetc(fp); //write file into an array
l++;
}
fclose(fp);
msg[l] = '\0'; //Append string with end of text char
}
else
{
char c1 = '0';
while(c1 != '\0')
{
c1 = *(syscl+l-12); //write file into an array
//printf("\n %c", msg[l]);
msg[l] = c1;
l++;
}
}
msg1 = createheader(req1, req2, req3, tp, curr, l); //Create Header
for (i=0; i<12; i++)
{
msg[i] = *(msg1+i);
}
drop = rand()%10+1; //to simulate dropped packets
if (drop > 2) //Drop with a given prob (i.e (x-1)/10)
{
sendto(listenfd, &msg, MAXLINE, 0,(struct sockaddr*)&cliaddr, sizeof(cliaddr));
puts(msg);
}
l = 0;
}
}
char* createheader(int req1, int req2, int req3, char tp, int seq, int len) //header
{
static char msg1[10000];
//int len;
//char req;
msg1[0] = '$'; //Start Char
msg1[1] = tp; //Type of req.
//msg1[3] = '0';
msg1[4] = seq%256+'0'; //4-7: seq no in little endian
msg1[5] = (seq/256)%256+'0';
msg1[6] = (seq/65536)%256+'0';
msg1[7] = (seq/(65536*256))%256+'0';
msg1[8] = req1;
msg1[9] = req2;
msg1[10] = req3;
msg1[11] = '0';//Reserved Byte, Also for alignment
//len = strlen(msg1);
msg1[2] = (len +'0')%256+'0'; //2-3:Length in lil' endian
msg1[3] = ((len+'0')/256)%256+'0';
return msg1;
}
char* sysfunc(int req1, int req2, int req3)
{
static char syscl[100];
//printf("\ncomm %d\n", req2);
//printf("\ncomm %d\n", req3);
switch (req2)
{
case 1: //Hardware
{
switch (req3)
{
case 1: strcpy(syscl, "lscpu > sysstat.txt\0"); //CPU
break;
case 2: strcpy(syscl, "lsmem > sysstat.txt\0"); //Memoru=y
break;
case 3: strcpy(syscl, "lsblk > sysstat.txt\0"); //HDDs
break;
case 4: strcpy(syscl, "lspci > sysstat.txt\0"); //PCI Add-Ons
break;
default: strcpy(syscl, "\nInvalid Command...\n\0"); //Default
break;
}
}
break;
case 2: //OS
{
switch (req3)
{
case 1: strcpy(syscl, "hostname > sysstat.txt\0");//Hostname
break;
case 2: strcpy(syscl, "hostnamectl > sysstat.txt\0");//OS and Kernel
break;
case 3: strcpy(syscl, "uptime > sysstat.txt\0");//Uptime
break;
default: strcpy(syscl, "\nInvalid Command...\n\0");
break;
}
}
break;
case 3: //Network
{
switch (req3)
{
case 1: strcpy(syscl, "ip link show > sysstat.txt\0");//Ifs
break;
case 2: strcpy(syscl, "ifconfig | grep ether > sysstat.txt\0");//Ethernet
break;
case 3: strcpy(syscl, "ifconfig > sysstat.txt\0");//IP
break;
case 4: strcpy(syscl, "route -n > sysstat.txt\0");//Routing Table
break;
default: strcpy(syscl, "\nInvalid Command...\n\0");
break;
}
}
break;
default: strcpy(syscl, "\nInvalid Command...\n\0");
break;
}
return syscl;
}
Have been at it for 2 days. Unable to figure out where I went wrong. Since the server is showing no reaction, I am assuming there is something wrong in the initial portions (recvfrom on the server side) and therefore have split the code in such a way. Sorry if I have made some obvious noob mistakes.
It seems you chose a wrong local IP address of interface in the server (where did you get the "127.0.0.2" from?) - if I change
mreq.imr_interface.s_addr = inet_addr(myIP);
to
mreq.imr_interface.s_addr = INADDR_ANY;
the server starts receiving.
Aren't 127.0.0.0/8 block of local addresses?
These are loopback addresses (see What is the rest of the 127.0.0.0/8 address space used for?). The comment local IP address of interface in the definition of struct ip_mreq may be a bit misleading, since it can remind one of localhost, but it actually means an IP address assigned to an interface of the local host seen from outside.
It is still not working with INADDR_ANY.
As so often, not working is an insufficient problem description. You could gather more information e. g. by running the server with strace -enetwork …. And I recommend to leave aside unnecessary complications like Mininet until the programs work on a pure network.
I'm baffled by an issue i'm having when trying to get UTF-8 and swedish characters ÅÄÖ to print correctly in a UNIX-talk clone.
I've set the locale with setLocale() to sv_SE and i'm using wide characters to try to display the characters correctly, lowercase åäö works just fine but somehow the capital variant does not work.
Below is the code in its entirety, i suspect that there is something i'm missing with the character sizes in reader() sender() or putch().
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <ncurses.h>
#include <pthread.h>
#include <signal.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sched.h>
#include <pthread.h>
#include <locale.h>
#include <wchar.h>
#define MATRIXSIZE 1000
#define STACKSIZE 10000
#define CHATLEN 2048
#include <syslog.h>
int r = 0, i = 0, mode = -1;
wchar_t mybuf[CHATLEN], tmbuf[CHATLEN];
WINDOW *me;
WINDOW *them;
struct stuff {
unsigned int col, row, size, realsize;
pid_t childpid;
pid_t mainpid;
char matrix[MATRIXSIZE];
char nukeline[1024];
int nukesize;
int terminate;
struct massaskit {
int writechan;
int readchan;
int sockfd;
struct sockaddr_in server;
struct sockaddr_in writeclient;
struct sockaddr_in readclient;
int c;
struct hostent *serverhost;
char hostname[256];
uint16_t port;
} bertil;
};
pthread_mutex_t scr_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_t sendthread; // Thread that listens to user's typing, and
// puts the characters on the screen, and
// transmits them over the network.
pthread_t readthread; // Thread that reads characters from the network
// and shows them on the screen.
int srv1(void *ptr)
{
struct massaskit *sockstuff = (struct massaskit *)ptr;
int opt = 1;
if ((sockstuff->sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket();");
exit(-1);
}
sockstuff->server.sin_family = AF_INET;
sockstuff->server.sin_addr.s_addr = INADDR_ANY;
sockstuff->server.sin_port = htons(sockstuff->port);
setsockopt(sockstuff->sockfd, SOCK_STREAM, SO_REUSEADDR, &opt,
sizeof(opt));
if (bind
(sockstuff->sockfd, (struct sockaddr *)&sockstuff->server,
sizeof(sockstuff->server)) < 0) {
perror("bind failed");
exit(-1);
}
if ((listen(sockstuff->sockfd, 3)) < 0)
{
perror("listen");
exit(-1);
}
sockstuff->c = sizeof(struct sockaddr_in);
printf("waiting for readchan on %i sockstuff->port..\n",
sockstuff->port);
sockstuff->readchan =
accept(sockstuff->sockfd,
(struct sockaddr *)&sockstuff->readclient,
(socklen_t *) & sockstuff->c);
printf("got a connection! now need a connection on writechan (p:%i)\n",
sockstuff->port);
sockstuff->writechan =
accept(sockstuff->sockfd,
(struct sockaddr *)&sockstuff->writeclient,
(socklen_t *) & sockstuff->c);
printf("got a connection! both read/write (p:%i)\n", sockstuff->port);
shutdown(sockstuff->writechan, SHUT_RD);
shutdown(sockstuff->readchan, SHUT_WR);
if (close(sockstuff->sockfd) != 0)
{
exit(1);
}
return 0;
}
int cli1(void *ptr)
{
/* srv1 starts with readchan, we start with writechan :-) */
struct massaskit *sockstuff = (struct massaskit *)ptr;
int opt = 1;
sockstuff->sockfd = -1; /* make it broken so other function understand */
if ((sockstuff->writechan = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("writechan->socket()");
exit(-1);
}
else
{
printf("socket init is ok.got fd[%i] [writechan]\n",
sockstuff->writechan);
}
setsockopt(sockstuff->writechan, SOCK_STREAM, SO_REUSEADDR, &opt,
sizeof(opt));
if ((sockstuff->serverhost =
gethostbyname(sockstuff->hostname)) == NULL) {
perror("error in resolving hostname :/\n");
exit(-1);
}
else
{
printf("ok, resolved host, now making connection [writechan]!\n");
}
memset(&sockstuff->server, '\0', sizeof(struct in_addr));
sockstuff->server.sin_family = AF_INET;
memcpy(&sockstuff->server.sin_addr.s_addr,
sockstuff->serverhost->h_addr,
(size_t) sockstuff->serverhost->h_length);
sockstuff->server.sin_port = htons(sockstuff->port);
if (connect
(sockstuff->writechan, (struct sockaddr *)&sockstuff->server,
sizeof(sockstuff->server)) == -1) {
perror("connection");
exit(-1);
}
else
{
printf("%s%s", "writechan established,starting readchan and", "sleeping 2s so other end can initalize the readchan.\n");
}
if ((sockstuff->readchan = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket();");
exit(-1);
}
else
{
printf("readchan socket init ok.\n");
fflush(stdout);
}
setsockopt(sockstuff->readchan, SOCK_STREAM, SO_REUSEADDR, &opt,
sizeof(opt));
if ((sockstuff->serverhost = gethostbyname(sockstuff->hostname)) == NULL)
{
perror("error in recieve channel, could'nt resolve host bailing.\n");
exit(-1);
}
else
{
printf("readchan could resolve host nice shit alabama\n");
fflush(stdout);
}
memset(&sockstuff->server, '\0', sizeof(struct in_addr));
sockstuff->server.sin_family = AF_INET;
memcpy(&sockstuff->server.sin_addr.s_addr,
sockstuff->serverhost->h_addr,
(size_t) sockstuff->serverhost->h_length);
sockstuff->server.sin_port = htons(sockstuff->port);
if (connect
(sockstuff->readchan, (struct sockaddr *)&sockstuff->server,
sizeof(sockstuff->server)) == -1) {
perror("connect()");
exit(-1);
}
else
{
printf("read chan estabiled. starting program!\n");
fflush(stdout);
}
return 0;
}
void putch(WINDOW * win, wchar_t ch)
{
syslog(LOG_INFO, "%04x", ch);
if (ch == 4 || ch == 7) // Translate left-arrow, backspace to CTL-H
ch = '\b';
if(ch < ' ' && ch != '\t' &&
ch != '\n' && ch != '\b'
)
{
return;
}
pthread_mutex_lock(&scr_mutex); // Get exclusive access to screen.
wechochar(win, ch);
if (ch == '\b')
{
wdelch(win);
refresh();
}
pthread_mutex_unlock(&scr_mutex);
}
void setupscreen()
{
int rows, cols;
initscr();
cbreak();
noecho();
intrflush(stdscr, FALSE);
rows = (LINES - 3) / 2;
cols = COLS - 2;
me = newwin(rows, cols, 1, 1);
them = newwin(rows, cols, rows + 2, 1);
idlok(me, TRUE);
scrollok(me, TRUE);
keypad(me, TRUE);
idlok(them, TRUE);
scrollok(them, TRUE);
border(0, 0, 0, 0, 0, 0, 0, 0);
move(rows + 1, 1);
hline(0, cols);
refresh();
}
void* sender(void *ptr) {
struct stuff *s = (struct stuff *)ptr;
setupscreen();
int ch;
while (1)
{
if (i > CHATLEN - 1)
{
i = 0;
}
ch = wgetch(me);
mybuf[i] = ch;
if (ch == KEY_RESIZE)
{
clear();
endwin();
setupscreen();
wchar_t *p = &mybuf[0];
while (&(*p) < &mybuf[CHATLEN - 1])
{
putch(me, (*p));
p++;
}
p = &tmbuf[0];
while (&(*p) < &tmbuf[CHATLEN - 1])
{
putch(them, (*p));
p++;
}
refresh();
}
else
{
putch(me, mybuf[i]);
int writefd = s->bertil.writechan;
write(writefd, &mybuf[i], sizeof(mybuf[i]));
}
i++;
}
pthread_cancel(sendthread);
return NULL;
}
void* reader(void *ptr) {
struct stuff *s = (struct stuff *)ptr;
int ch;
while(1)
{
if(r> CHATLEN - 1)
{
r = 0;
}
int readfd=s->bertil.readchan;
if((read(readfd,&ch,sizeof(ch))) == 0)
{
endwin();
refresh();
return 0;
}
tmbuf[r] = ch;
putch(them, tmbuf[r]);
r++;
}
pthread_cancel(readthread);
return NULL;
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL, "sv_SE");
memset(mybuf, 0, CHATLEN);
memset(tmbuf, 0, CHATLEN);
struct stuff s;
memset(&s, 0, sizeof(struct stuff));
if (argc == 1)
{
printf("usage %s port [host server on port]\n", argv[0]);
printf("usage %s port host [connecto host:port]\n", argv[0]);
exit(1);
}
else if (argc == 3)
{
s.bertil.port = (uint16_t) atoi(argv[1]);
memset(s.bertil.hostname, 0, 256);
memcpy(s.bertil.hostname, argv[2], strlen(argv[2]));
cli1(&s.bertil);
}
else if (argc == 2)
{
s.bertil.port = (uint16_t) atoi(argv[1]);
srv1(&s.bertil);
}
pthread_create(&readthread, NULL, reader, &s);
pthread_create(&sendthread, NULL, sender, &s);
pthread_join(sendthread, NULL);
pthread_join(readthread,NULL);
}
If you want to try out the program compile it as follows:
gcc file.c -lpthread -lncurses
To serve:
./a.out 1234
To connect:
./a.out 1234 localhost
Any help would be greatly appreciated!
Actually, wchar_t is enough bits, and sign-extension problems do not appear likely.
However, the application using ncurses in two threads (sender and reader), and unless you have compiled it specially and allowed for mutexes, it won't work well. ncurses (like any implementation of curses) uses global variables for maintaining the screen. Multiple threads will exercise the library in unexpected ways.
Further reading:
Official releases (ncurses FAQ):
5.7 (2 November 2008). This provides rudimentary support for threaded applications. It also distributes tack separately.
curs_threads - curses thread support (ncurses manual page)
Try using unsigned char instead of int in your functions.
In putch, you do not need wchar_t, unsigned char (one byte) is fine in UTF-8 (http://www.science.co.il/language/Character-code.asp?s=1252).
Program: In this project, i have to read a file in a client program, and send it to the server program
Problem: In the resulting file, i am getting all the characters in the client program, along with some unwanted characters in the end.
What i think is the reason: If i put 15 characters in the file to be sent, i get correct output (note that my buffer size, i.e., number of characters i send at one time, is 16). If i use 14 or less characters, i get 1 '\00' at the end. If i use even less characters, then i get a '\00' corresponding to each of the missing ones. Maybe my '\0' (that is what i set empty space, or the extra characters in my buffer as) are getting represented in output file as '\00'.
Here's the client program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#define BUFSIZE 16
#define USAGE \
"usage:\n" \
" transferclient [options]\n" \
"options:\n" \
" -s Server (Default: localhost)\n" \
" -p Port (Default: 8888)\n" \
" -o Output file (Default foo.txt)\n" \
" -h Show this help message\n"
/* Main ========================================================= */
int main(int argc, char **argv) {
int option_char = 0;
char *hostname = "127.0.0.1";
unsigned short portno = 8888;
char *filename = "foo.txt";
// Parse and set command line arguments
while ((option_char = getopt(argc, argv, "s:p:o:h")) != -1) {
switch (option_char) {
case 's': // server
hostname = optarg;
break;
case 'p': // listen-port
portno = atoi(optarg);
break;
case 'o': // filename
filename = optarg;
break;
case 'h': // help
fprintf(stdout, "%s", USAGE);
exit(0);
break;
default:
fprintf(stderr, "%s", USAGE);
exit(1);
}
}
/* Socket Code Here */
int sockfd = 0, n = 0;
char recvBuff[BUFSIZE], sendBuff[BUFSIZE];
struct sockaddr_in serv_addr;
if((sockfd = socket(AF_INET, SOCK_STREAM, 0))< 0) {
printf("Error: Could not create socket \n");
return 1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
serv_addr.sin_addr.s_addr = inet_addr(hostname);
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0) {
printf("Error: Connect Failed\n");
return 1;
}
FILE *fp = fopen(filename, "rb");
if(fp == NULL) {
printf("Error: file not found.\n");
return 0;
}
fseek(fp, 0, SEEK_END);
int size = ftell(fp);
fseek(fp, 0, SEEK_SET);
memset(sendBuff, '\0', BUFSIZE);
sprintf(sendBuff, "%d", size);
write(sockfd, sendBuff, strlen(sendBuff));
printf("size: %d\n", size);
memset(sendBuff, '\0', BUFSIZE);
int temp = fread(sendBuff, 1, BUFSIZE, fp);
while(temp > 0) {
write(sockfd, sendBuff, BUFSIZE);
memset(sendBuff, '\0', BUFSIZE);
temp = fread(sendBuff, 1, BUFSIZE, fp);
}
fclose(fp);
printf("done sending data to server.\n");
memset(recvBuff, '\0', BUFSIZE);
while((n = read(sockfd, recvBuff, BUFSIZE)) > 0) {
recvBuff[n] = '\0';
if(fputs(recvBuff, stdout) == EOF) {
printf("Error: Fputs error\n");
}
printf("\n");
}
if( n < 0) {
printf("Read Error\n");
}
return 0;
}
Here's the server program:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#if 0
/*
* Structs exported from netinet/in.h (for easy reference)
*/
/* Internet address */
struct in_addr {
unsigned int s_addr;
};
/* Internet style socket address */
struct sockaddr_in {
unsigned short int sin_family; /* Address family */
unsigned short int sin_port; /* Port number */
struct in_addr sin_addr; /* IP address */
unsigned char sin_zero[...]; /* Pad to size of 'struct sockaddr' */
};
/*
* Struct exported from netdb.h
*/
/* Domain name service (DNS) host entry */
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
}
#endif
#define BUFSIZE 4096
#define CLIENTBUFSIZE 16
#define USAGE \
"usage:\n" \
" transferserver [options]\n" \
"options:\n" \
" -p Port (Default: 8888)\n" \
" -f Filename (Default: bar.txt)\n" \
" -h Show this help message\n"
int num_of_digits(int num) {
if(num <= 0) printf("Error: size <= 0.\n");
if(num <= 0) exit(1);
int n = 0;
while(num > 0) {
n++;
num /= 10;
}
return n;
}
int main(int argc, char **argv) {
int option_char;
int portno = 8888; /* port to listen on */
char *filename = "bar.txt"; /* file to transfer */
// Parse and set command line arguments
while ((option_char = getopt(argc, argv, "p:f:h")) != -1){
switch (option_char) {
case 'p': // listen-port
portno = atoi(optarg);
break;
case 'f': // listen-port
filename = optarg;
break;
case 'h': // help
fprintf(stdout, "%s", USAGE);
exit(0);
break;
default:
fprintf(stderr, "%s", USAGE);
exit(1);
}
}
/* Socket Code Here */
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[BUFSIZE], recvBuff[BUFSIZE];
listenfd = socket(AF_INET, SOCK_STREAM, 0);
printf("socket retrieve success\n");
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(portno);
bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));
if(listen(listenfd, 5) == -1) {
printf("Failed to listen\n");
return -1;
}
int size, temp;
while(1) {
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); // accept awaiting request
memset(recvBuff, '\0', BUFSIZE);
read(connfd, recvBuff, BUFSIZE);
sscanf(recvBuff, "%d", &size);
temp = strlen(recvBuff) - num_of_digits(size);
size -= temp;
printf("size: %d\n", size);
printf("Data from client:\n%s", (recvBuff + num_of_digits(size)));
FILE * fp = fopen(filename, "wb");
int temp;
while(size > 0) {
read(connfd, recvBuff, CLIENTBUFSIZE);
printf("%s", recvBuff);
temp = fwrite(recvBuff, 1, CLIENTBUFSIZE, fp);
size -= temp;
printf("temp: %d\n", temp);
printf("Remaining data: %d\n", size);
}
fclose(fp);
printf("size: %d\n", size);
printf("\n\nFinished reading from client.\n");
strcpy(sendBuff, "Message from server: your message has been recieved.");
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
return 0;
}
Here's the input file content:
12345678901234
Here's the output file content:
12345678901234
\00
The read() system call returns the number of bytes read (or -1 for error). You are throwing the result away and writing the entire buffer of CLIENTBUFSIZE bytes to your file even if you were sent fewer than 16 bytes.
I am reading IPS and PORTS of few Sockets through this text file IP_CONFIG.txt
"192.168.128.3" IP_CSR
"192.168.128.2" IP_HMIR
"192.168.128.1" IP_OBCUR
"192.168.128.4" IP_ASRR
"127.0.0.1" IP_RSOR
"127.0.0.1" IP_RSO_DR
1901 PORT_CSR
1901 PORT_HMIR
1901 PORT_OBCUR
3567 PORT_ASRR
4444 PORT_RSOR
7777 PORT_RSO_DR
I implemented the code with the following way..
1) I saved all different IP addresses in different char strings and Ports with integers.
2) I call these variables when defining socket addresses.
Problem: Although it is giving correct values while calling these variables with printf , but i cann't load these variables while definining IP adrreses and PORTS of different systems
The complete CODE is here.
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#define MAX_DATE 100
# define BUFLEN 1024
#define ROW 11
#define COL 2
#define MAXWORDS 24
int main(int argc, char **argv)
{
//Declared variables
int sock, sock_RST; // socket name
int bytes_read; // variable for recvfrom
int addrlen; // length of address
int i = 0, j = 0, k = 0, z = 0; // counters
unsigned char ca[BUFLEN], last_OBCU_msg[BUFLEN], last_HMI_msg[BUFLEN],
rcvd_ASR_msg[BUFLEN]; // Data buffers
struct sockaddr_in server_addr, HMI_addr, OBCU_addr, ASR_addr, RSO_addr,
test_addr; //addresses IP PORT
struct sockaddr_in RSO_addr_d;
const char yes = 1;
int TAG_ASR = 0;
// Create a lof file
time_t now;
char the_date[MAX_DATE];
the_date[0] = '\0';
now = time(NULL );
strftime(the_date, MAX_DATE, "CS_LOG_%H_%M_%d_%m_%Y" ".txt", gmtime(&now));
chdir("/home/bsnayak/CS_LOG/");
FILE *file = fopen(the_date, "a");
//Read IPS and PORTS from a text file
//char* file="C:\\Documents and Settings\\Supernovah\\Desktop\\Supernovah.bin";
//FILE* pFile = fopen( file, "rb" );
char* file_text = "/home/bsnayak/IP_CONFIG.txt";
FILE *fp = fopen(file_text, "r");
int ii = 0, jj;
char *words = NULL, *word = NULL, c;
char *allwords[MAXWORDS];
while ((c = fgetc(fp)) != EOF)
{
ii++;
if (c == '\n')
{
c = ' ';
}
words = (char *) realloc(words, (ii + 1) * sizeof(char));
words[ii - 1] = c;
}
words[ii] = '\0';
word = strtok(words, " ");
ii = 0;
while (word != NULL && ii < MAXWORDS)
{
//printf("%s\n",word);
allwords[ii] = malloc(strlen(word) + 1);
strcpy(allwords[ii], word);
word = strtok(NULL, " ");
//allwords[ii][strlen(word)] = '\0';
ii++;
}
if (error_name)
printf("\nNow printing each saved string:\n");
/*for (jj=0; jj<ii; jj++){
printf("String %d: %s\n", jj, allwords[jj]);
//free(allwords[jj]);
}*/
char *IP_CS = allwords[0];
char *IP_HMI = allwords[2];
char *IP_OBCU = allwords[4];
char *IP_ASR = allwords[6];
char *IP_RSO = allwords[8];
char *IP_RSO_D = allwords[10];
int PORT_CS = atoi(allwords[12]);
int PORT_HMI = atoi(allwords[14]);
int PORT_OBCU = atoi(allwords[16]);
int PORT_ASR = atoi(allwords[18]);
int PORT_RSO = atoi(allwords[20]);
int PORT_RSO_D = atoi(allwords[22]);
//printf("The IPs are \n %s\n %s\n %s\n %s\n %s\n %s\n",IP_CS,IP_HMI,IP_OBCU,IP_ASR,IP_RSO,IP_RSO_D);
//printf("The PORTSs are \n %d\n %d\n %d\n %d\n %d\n %d\n",PORT_CS,PORT_HMI,PORT_OBCU,PORT_ASR,PORT_RSO,PORT_RSO_D);
//free(allwords[MAXWORDS]);
setbuf(stdout, NULL );
addrlen = sizeof(struct sockaddr_in);
// Create the Socket for all connections except RST
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("Socket Creation Error");
exit(1);
}
// Create the Socket for RST section
if ((sock_RST = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("Socket Creation Error");
exit(1);
}
// make CS socket non blocking and reusable
fcntl(sock, F_SETFL, O_NONBLOCK);
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &yes, sizeof(int)) < 0)
{
perror("Reuse option\n");
close(sock);
exit(1);
}
// make RST socket non blocking and reusable
fcntl(sock_RST, F_SETFL, O_NONBLOCK);
if (setsockopt(sock_RST, SOL_SOCKET, SO_REUSEADDR, (char*) &yes, sizeof(int))
< 0)
{
perror("Reuse option\n");
close(sock_RST);
exit(1);
}
printf("\nchecked1\n");
// Control server properties
bzero(&(server_addr.sin_zero), sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT_CS);
server_addr.sin_addr.s_addr = inet_addr(IP_CS); //inet_addr("192.168.128.3"); //
// HMI server properties
bzero(&(HMI_addr.sin_zero), sizeof(HMI_addr));
HMI_addr.sin_family = AF_INET;
HMI_addr.sin_port = htons(PORT_HMI);
HMI_addr.sin_addr.s_addr = inet_addr(IP_HMI);
// OBCU server properties
bzero(&(OBCU_addr.sin_zero), sizeof(OBCU_addr));
OBCU_addr.sin_family = AF_INET;
OBCU_addr.sin_port = htons(PORT_OBCU);
OBCU_addr.sin_addr.s_addr = inet_addr(IP_OBCU);
// ASR Server properties
bzero(&(ASR_addr.sin_zero), sizeof(ASR_addr));
ASR_addr.sin_family = AF_INET;
ASR_addr.sin_port = htons(PORT_ASR);
ASR_addr.sin_addr.s_addr = inet_addr(IP_ASR);
// RSO server properties
bzero(&(RSO_addr.sin_zero), sizeof(RSO_addr));
RSO_addr.sin_family = AF_INET;
RSO_addr.sin_port = htons(PORT_RSO);
RSO_addr.sin_addr.s_addr = inet_addr(IP_RSO);
// RSO destination properties (To which you send string content)
bzero(&(RSO_addr_d.sin_zero), sizeof(RSO_addr_d));
RSO_addr_d.sin_family = AF_INET;
RSO_addr_d.sin_port = htons(PORT_RSO_D);
RSO_addr_d.sin_addr.s_addr = inet_addr(IP_RSO_D);
// BIND Controlserver to the main socket
if (bind(sock, (struct sockaddr *) &server_addr, sizeof(struct sockaddr))
!= 0)
{
perror("Bind Error");
close(sock);
exit(1);
}
printf("checked2\n");
// Bind RSO for second socket
if (bind(sock_RST, (struct sockaddr *) &RSO_addr, sizeof(struct sockaddr))
!= 0)
{
perror("Bind Error");
close(sock_RST);
exit(1);
}
printf("checked3\n");
while (1)
{
addrlen = sizeof(test_addr);
bytes_read = recvfrom(sock, ca, BUFLEN, 0, (struct sockaddr *) &test_addr,
&addrlen);
//printf("checked4\n");
if (test_addr.sin_addr.s_addr == OBCU_addr.sin_addr.s_addr)
{
sendto(sock, ca, bytes_read, 0, (struct sockaddr *) &HMI_addr,
sizeof(HMI_addr));
memcpy(last_OBCU_msg, ca, sizeof(ca));
memset(ca, 0, BUFLEN);
printf("OHS Received\n");
}
}
fclose(file);
return 0;
}
But if i remove the varoable names and assign IP and Ports manually it works perfectly but why cann't use them as variables. Kindly suggest necessary modifications, suggestions..
The IP addresses as read from the file are enclosed by "-signs.
That is you do not pass "1.2.3.4" to inet_addr() but "\"1.2.3.4\"". And as "1.2.3.4" isn't a valid IP address (as 1.2.3.4 would be) the function fails.
Just printing them out or inspecting them using a debugger would have shown you this.