error when connecting server and using system function in c - c

I'm new in c and especially in sockets and if this question is silly i'm sorry. Here is my code:
/****************** SERVER CODE ****************/
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int main(){
int welcomeSocket, newSocket;
char buffer[1024];
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(7891);
serverAddr.sin_addr.s_addr = 0;
memset(serverAddr.sin_zero, '\0', sizeof(serverAddr.sin_zero));
bind(welcomeSocket, (struct sockaddr *) &serverAddr,
sizeof(serverAddr));
if(listen(welcomeSocket,5)==0)
printf("Listening\n");
else
printf("Error\n");
addr_size = sizeof serverStorage;
newSocket = accept(welcomeSocket,
(struct sockaddr *) &serverStorage, &addr_size);
strcpy(buffer,"Hello World\n");
send(newSocket,buffer,13,0);
memset(buffer, '\0', 1024);
while(recv(newSocket, &buffer, 1024, 0) > 0)
{
printf("%s", system(buffer));
memset(buffer, '\0', 1024);
}
return 0;
}
This is my server and i'm connecting with telnet(I know its not secure and let any user execute any command in server is neither but its for educational purposes). when i type "ls"(server program is run on linux) it gives me back this error not found
Segmentation fault (core dumped) and disconnects me. I hope you can help. thanks

Your program is crashing because of this line:
printf("%s", system(buffer));
as stated here: http://linux.die.net/man/3/system
the system() call is returning an integer, not a char*.
for what you want, you could use popen().
see the answer on this question for an example:
How to execute a command and get output of command within C++ using POSIX?
or
How to get the output of grep in C

Related

segmentation fault(core dump created) in recvfrom

I was writing a simple C code to create a lisening socket. The code is teh following:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>
void main() {
struct sockaddr_in server;
struct sockaddr_in client;
int clientlen;
char buf[1500];
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
memset((char *)&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(9090);
if(bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0)
error("ERROR on binding");
while(1) {
bzero(buf, 1500);
recvfrom(sock, buf, 1500-1, 0, (struct sockaddr *) &client, &clientlen);
printf("%s\n", buf);
printf("%d - %s\n", client.sin_port, client.sin_addr.s_addr);
}
close(sock);
}
The code compile with no problem but when I connect to the server with a client using netcat:
nc -u 10.0.2.4 9090
and I send some message, the message are replied and then I get the error. DO someone knows why I get this behaviour?
Thank you.
There are two main issues here. First, clientlen is expected to contain the size of the address structure before recvfrom is called, but it is uninitialized. So set it as follows:
int clientlen = sizeof(client);
Second, you're using %s to print client.sin_addr.s_addr but that field is not a string. You should use inet_ntoa to convert a struct inaddr_t to a string:
printf("%d - %s\n", ntohs(client.sin_port), inet_ntoa(client.sin_addr));

Basic UDP Client/Server won't work?

I am hoping that this is a relatively simple answer to my question. I am attempting to learn how to program in sockets and I just can't seem to get a basic UDP example working. I am attempting to just send a string "hello" from one computer to another read it on the screen.
I started with this website
https://www.programminglogic.com/sockets-programming-in-c-using-udp-datagrams/
then tried:
https://www.abc.se/~m6695/udp.html
I have also looked at
https://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html
but it seems that each time I try to code nothing happens. I get no errors, I just don't get any communication. I can ping my server computer from my client computer at least
My setup:
I currently have two computers one running Ubuntu 16.04 the other 14.04.
I was hoping to start off with something easy by connecting them directly. But I have tried connecting them through a switch. No success.
On the "server" computer I set up my network card to have by opening the terminal and
sudo ifconfig enps60 192.168.1.1 netmask 255.255.255.0
To create my server code in terminal I type
gedit udp_server.c
and in the text editor I type
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <ctype.h>
int main()
{
int udpSocket, nBytes;
char buffer[1024];
struct sockaddr_in serverAddr, cientAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size, client_addr_size;
/* Create UDP socket */
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
/* Configure settings in address struct */
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(0);
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.1");
memset(serverAddr.sin_zero, '\0', sizeof(serverAddr.sin_zero));
/* Bind Socket */
bind(udpSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
printf("bind complete. Port number = %d\n", ntohs(serverAddr.sin_port));
addr_size = sizeof(serverStorage);
while(1)
{
nBytes = recvfrom(udpSocket, buffer, 1024, 0, (struct sockaddr *)%clientAddr, &addr_size);
printf("any bytes: %d\n, nBytes);
}
}
I then compile my code in terminal by typing
gcc -o udp_server udp_server.c
On my client computer (ubuntu 14.04) I open the terminal and type
sudo ifconfig eth0 192.168.1.2 netmask 255.255.255.0
then to create my client code in terminal I type
gedit udp_client.c
and in the text editor I type
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main()
{
int udpSocket, portNum, nBytes;
char buffer[1024] = "hello";
struct sockaddr_in serverAddr;
socklen_t addr_size;
unsigned int alen;
/*create UDP socket */
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
/* Configure settings in address struct */
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(0);
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.1");
memset(serverAddr.sin_zero, '\0', sizeof(serverAddr.sin_zero));
addr_size = sizeof(serverAddr);
while(1)
{
printf("sending %s\n", buffer);
nBytes = strlen(buffer);
sendto(udpSocket, buffer, nBytes, 0, (struct sockaddr *)&serverAddr, addr_size);
sleep(1);
}
return 0;
}
I apologize if my code isn't that polished also.
Ok, well thanks guys for all the suggestions, but I do have some code that works.
I still am very unsure how any of this works, but for starters I was selecting an incorrect port number. According to Steve Summitt I checked my connection using Netcat, and when I would look at port 0 netcat would kindly let me know that I can't choose a port number that low. This is a bit confusing as everything I am reading says that port numbers start at 0. Also there is a thing about trying not to use well known ports which used to be 0-255 but is now 0-1023. I was trying to figure out if I know what ports I can use or not and I came across this.
https://sort.veritas.com/public/documents/vie/7.3/aix/productguides/html/sfcfsha_config/apgs04s03.htm
Although I am unsure the context is only when using IPv6 protocol?
Also I found this list.
https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
I guess there are a bunch of applications on every machine that uses these ports?
The quick solution: I set the port to 1024 and forgot to bind my client socket to my client computers network card. I also changed the way I do memset (I thought I understood it, but I might not)
for the complete solution:
Current Setup:
I have two Ubuntu machines connected together by a simple switch. The machines are what I am calling a server (ubuntu 16.04) and a client (ubuntu 14.04).
The first step I did is assign static IPs to each machine (I think this is only recommended for my server computer, but I didn't know how to get my DHCP address of my client in c).
in my server computer I opened my terminal (ctrl + alt + t)
sudo ifconfig enp6s0 192.168.1.1 netmask 255.255.255.0
in the client computer I opened my terminal and typed
sudo ifconfig eth0 192.168.1.2 netmask 255.255.255.0
now going back to the server computer in terminal I typed
gedit udp_server.c
which opened up a text editor
/************** UDP Server Code *****************/
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <ctype.h>
int main()
{
int udpSocket, nBytes;
char buffer[5];
struct sockaddr_in serverAddr, clientAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size, client_addr_size;
int i;
/* Create UDP socket */
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
/* Configure settings in address struct */
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(1024);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
memset(serverAddr.sin_zero, '\0', sizeof(serverAddr.sin_zero);
/* Bind socket with address struct */
bind(udpSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
printf("bind complete port number %d\n", ntohs(serverAddr.sin_port));
/* Initialize size variable to be used later on */
addr_size = sizeof(serverStorage);
while(1)
{
nBytes = recvfrom(udpSocket, buffer, 5, (struct sockaddr *)&clientAddr, &addr_size);
printf("any bytes %d\n", nBytes);
}
return 0;
}
now for the client code I typed (on my client computer)
gedit udp_client.c
which opened up a text editor
/************ UDP client code **********/
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
int main()
{
int udpSocket, portNum, nBytes;
char buffer[1024] = "hello";
struct sockaddr_in serverAddr, clientAddr;
socklen_t addr_size;
unsigned int alen;
/* Create UDP socket */
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
/* Configure client settings in address struct */
memset((char *)&clientAddr, 0, sizeof(clientAddr));
clientAddr.sin_family = AF_INET;
clientAddr.sin_addr.s_addr = inet_addr("192.168.1.2");
clientAddr.sin_port = htons(0);
if(bind(udpSocket, (struct sockaddr *)&clientAddr, sizeof(clientAddr)) < 0)
{
perror("bind failed");
return 0;
}
printf("client bound");
/* configure server settings in struct */
memset((char *)&serverAddr, '0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(1024);
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.1");
printf("the socket ip addr is: %s\n", inet_ntoa(clientAddr.sin_addr));
addr_size = sizeof(serverAddr);
while(1)
{
sleep(2);
nBytes = strlen(buffer);
if(sendto(udpSocket, buffer, nBytes, 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1)
{
perror("send to");
exit(1);
}
printf("sent %s\n", buffer);
}
return 0;
}
some extra notes
I actually don't know if I need to bind my sockets on my client side? I bound it to port 0 and everything worked peachey. I am thinking might run into issues if I try to receive from the server?
I am still working on a metaphor for how to think about ports
I am going with that the IP address is the network card address (city) and the port number is the address within that city (task, application). Like many people can reside in a city, many tasks or programs can reside on a machine and each one might want to communicate to the world.
This is only the most basic information (I don't cover other things like connect(), send(), write(), sendmsg() as I don't know how to use them)
hopefully this post makes it easier on the next guy.

Client connects to server randomly

I am trying to write a simple client/server program where the server first connects to the client, and sends the client a message. The client then echoes back the message to the server in uppercase.
The thing is, the connection is random; sometimes the client connects and sometimes it doesn't.
EDIT: when it doesn't connect, I get an "Address already in use" error. Is there some way to free the address on the server side?
SERVER.C
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
int main(){
int welcomeSocket, newSocket, portNum, clientLen, nBytes;
char buffer[1024];
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
int counter = 0;
welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
portNum = 7891;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(portNum);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
/*---- Listen on the socket, with 5 max connection requests queued ----*/
if(listen(welcomeSocket,5)==0)
printf("Listening\n");
else
printf("Error\n");
/*---- Accept call creates a new socket for the incoming connection ----*/
addr_size = sizeof serverStorage;
while(1){
newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
/* counter ++ ;*/
/* printf("client connected: %d\n",counter);*/
/*fork a child process to handle the new connection*/
if(!fork()){
/*---- Send message to the socket of the incoming connection ----*/
strcpy(buffer,"Hello World\n");
send(newSocket,buffer,13,0);
recv(newSocket,buffer,13,0);
/*---- Print the received message ----*/
printf("Data received: %s",buffer);
close(newSocket);
exit(0);
}
/*if parent, close the socket and go back to listening new requests*/
else{
close(newSocket);
}
}
return 0;
}
CLIENT.C
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <ctype.h>
int main(){
int clientSocket, portNum, nBytes;
char buffer[1024];
struct sockaddr_in serverAddr;
socklen_t addr_size;
clientSocket = socket(PF_INET, SOCK_STREAM, 0);
portNum = 7891;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(portNum);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
/*---- Connect the socket to the server using the address struct ----*/
addr_size = sizeof serverAddr;
connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
/*---- Read the message from the server into the buffer ----*/
nBytes = recv(clientSocket, buffer, 1024, 0);
/*---- Print the received message ----*/
printf("Data received: %s",buffer);
for (int i=0;i<nBytes-1;i++){
buffer[i] = toupper(buffer[i]);
}
send(clientSocket,buffer,nBytes,0);
return 0;
}
The "address already in use" error occurrs on a call to bind when a socket is already bound to that port. In the case of a listening TCP socket, that can happen when the program is restarted due to old connected sockets not being completely closed yet.
When binding a listening socket, you should set the SO_REUSEADDR socket option. This will allow you to bind a TCP listening socket in these situations.
int option = 1;
if (setsockopt(welcomeSocket, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) == -1) {
perror("setsockopt for SO_REUSEADDR failed");
exit(1);
}
This function should be called after socket but before bind.

Detect client is disconnected

I have a simple program that listens to a socket. Everything goes fine except when the connection is lost in while(1) cycle. In this case the program falls into read from socket for many times without result. How can I detect a disconnected client in while(1) cycle?
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include<string.h>
void printHex(char * bts )
{
char *s = bts;
int i=0;
do
{
printf("%02X ", (unsigned char ) *bts);
} while (* ++bts !=0);
printf("%s\n",s);
}
int main()
{
char str[100];
int listen_fd, comm_fd;
struct sockaddr_in servaddr;
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
bzero( &servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
servaddr.sin_port = htons(22000);
printf("binding\n");
bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
printf("listening\n");
listen(listen_fd, 10);
printf("accepting\n");
comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);
printf("accep done\n");
int cn =0;
while(1)
{
bzero( str, 100);
printf("will read\n");
int br= read(comm_fd,str,100);
printf("read done\n");
if (br>0)
{
printHex(str);
}
}
}
Change:
if (br>0)
{
printHex(str);
}
To:
if (br<=0) break;
printHex(str);
Also, your code mishandles the case where the first byte is zero. And you can't avoid this case because TCP does not preserve application message boundaries. You should just pass br to printHex so it will know how many characters to print.
You need to check the result of your read(). If the connection is closed you'll get a return-code for that.
From the manual page:
On error, -1 is returned, and errno is set appropriately.

simple TCP client serve model in C : client not recieving

im making a simple TCP client-server in c and im trying to send a message from the client to the server, but im having some problems with it.
The server does send the message (integer value > 0) but the client is unable to receive it (integer value > 0)
here is the code:
Client
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
int main()
{
int s_id;
char *msg = "hello";
struct sockaddr_in serv_addr;
s_id = socket (AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons (1156);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(s_id,(struct sockaddr *) &serv_addr, sizeof (struct sockaddr));
int r = recv (s_id, (char *) msg, 9, 0);
printf("%d \n", r );
printf("%s \n", msg );
return 0;
}
Server:
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int main()
{
int s_id;
char *msg = "connected";
struct sockaddr_in my_addr, remote_addr;
s_id = socket (PF_INET,SOCK_STREAM,0);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(1156);
my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
bind(s_id,(struct sockaddr *) &my_addr, sizeof(struct sockaddr));
listen (s_id,5);
int size = sizeof (struct sockaddr_in);
int new_sd = accept (s_id, (struct sockaddr *) &remote_addr, &size);
int s= send(new_sd, (void *)msg, 9, 0);
printf("%d \n", s );
return 0;
}
The outputs i get (after first starting the server, and then the client) are
server side: 9
client-side: -1
hello
I am using Ubuntu 11.04 and the gcc compiler.
I hope someone out there can help.
Thank you
Umar
char *msg = "hello";
This is a string literal. It's a constant, and you can't change it.
int r = recv (s_id, (char *) msg, 9, 0);
And there you're trying to write to it.
Change your declaration to:
char msg[20];
memset(msg, 0, sizeof(msg));
If you make that change, your code works as expected.
In C you're going to have to allocate and manage buffers - there's no free lunch :)
Also take note of the other answer from Nikolai N Fetissov - you really should be checking return codes from all the system calls.
You never check for errors after any of the system calls. All of socket(2), connect(2), etc. return -1 on failure, then you can print the error description with, say, perror(3) function. Each system call manual page lists possible errors.
Edit 0:
The real problem is probably what Brian points out - you are trying to receive data into read-only memory on the client. Does it die with a segfault?

Resources