My project is : Client receives the raw packet from the Ethernet saves it in a file called 'sniff_data.bin' and sends it to the server. Server receives the contents processes the packet( distinguishes between tcp,icmp,udp etc) and saves in a text file called 'info_agent_ report. txt' file. i think there is some mistake in my code. can anybody please guide me , help me out.
int main()
{
int sockfd, new_sockfd,log,n,x1,x2;
int server_len, client_len,len;
int cont,fh,cont2,x;
int result1;
struct sockaddr_in serveraddress;
struct sockaddr_in address;
struct sockaddr_in client_address;
FILE *ia_address;
char *fname = "/home/shishira/Desktop/packet_capture/info_agent_report.txt";
int buffsize=1024;
char buffer1[1024];
char buffer[1024];
char clntName[INET_ADDRSTRLEN];
if((sockfd = socket(AF_INET,SOCK_STREAM,0))>0)
printf("\n ---------------------------Task Agent---------------------------\n");
printf("\n Socket was created\n");
/* Name the socket. */
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_port = htons(9734);
server_len = sizeof(address);
bind(sockfd, (struct sockaddr *)&address, server_len);
/* Create a connection queue and wait INFO_AGENT_REPORTS */
listen(sockfd, 5);
while(1)
{
char ch;
printf("\n\n Task agent waiting...\n");
/* Accept a connection to collect report from INFO_AGENT */
client_len = sizeof(client_address);
new_sockfd = accept(sockfd,(struct sockaddr *)&client_address, &client_len);
if (new_sockfd==-1) { perror("Connection Not Accepted!!"); return(1);}
else
{
// x=fork();
// if (x==0) // child process starts
// {
printf("\n Information agent is connected\n");
//for displaying the client address
if(inet_ntop(AF_INET,&client_address.sin_addr.s_addr,clntName,sizeof(clntName))!=NULL)
{
ia_address = fopen("info_agent_report.txt","a+");
fprintf(ia_address,"\nFrom InformationAgent:%s\n",clntName);
fclose(ia_address);
}
printf("\n Task agent processed the contents and saved it in 'info_agent_report'
file\n\n");
log=open("info_agent_report.txt",O_CREAT|O_RDWR|O_APPEND,0777);
if(log==-1)
{
perror("cannot open info_agent_report file\n");
return(1);
}
do
{
x1=read(new_sockfd, buffer1, 1024);
x2=write(log,buffer1,x1);
}
while (x1>0);
data_process();//for processing the packet
close(log);
// } child process ends
close(new_sockfd);
}
}
I have written the code for displaying the client address in info_agent_report.txt. but is not getting dispalyed :(
To display client name: ( put this after accept )
char clntName[INET_ADDRSTRLEN]; // String to contain client address
if (inet_ntop(AF_INET, &clntAddr.sin_addr.s_addr, clntName,sizeof(clntName)) != NULL){
printf("Handling client %s/%d\n", clntName, ntohs(clntAddr.sin_port));
}
Or this:
char clntName[INET6_ADDRSTRLEN];
char portName[6];
if(getnameinfo(&client_address,sizeof client_address,clntName,sizeof(clntName),NULL,0,NI_NUMERICHOST|NI_NUMERICSERV|NI_NUMERICSCOPE)==0){
printf("Client = %s/%s\n",clntName,portName);
} else {
printf("Unable to get address\n");
}
Related
I have a very big problem that I have encountered with C. I wrote a C client program with a function that is supposed to send and receive data from a server also written in C. But it throws an error. 104. Below is the code for the function.
int send_and_receive_data(struct PatientData c, int rcv)
{
//recv is supposed to determine whether data will be received from the server. it's an integer that can either be 1 or 0
if (rcv)
{
/*create socket*/
int network_socket;
network_socket = socket(AF_INET,SOCK_STREAM,0);
//specify an address for the socket
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY;
int connection_status = connect(network_socket,(struct sockaddr *) &server_address, sizeof(server_address));
// check for error with the connection
if(connection_status == -1){
printf("There was an error making a connection to the remote socket\n\n");
}
//send data to the server
if(send(network_socket,&c,sizeof(c),0) < 0){
puts("Send Failed\n");
}
else
{
//puts("Data sent\n");
}
if(recv(network_socket,&s_results,sizeof(s_results),0) < 0)
{
printf("Receive Failed %d\n",errno);
printf("Sara Nakamya 2019-01-01 F Mary\n");
}
else
{
// output the received data
puts("Receive successful");
printf("%s %s %s %s\n",s_results.patient_name,s_results.patient_date,s_results.patient_category,s_results.patient_gender);
}
// and then close the socket
close(network_socket);
}
else
{
/*create socket*/
int network_socket;
network_socket = socket(AF_INET,SOCK_STREAM,0);
//specify an address for the socket
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY;
int connection_status = connect(network_socket,(struct sockaddr *) &server_address, sizeof(server_address));
// check for error with the connection
if(connection_status == -1){
printf("There was an error making a connection to the remote socket\n\n");
}
//send data to the server
if(send(network_socket,&c,sizeof(c),0) < 0){
puts("Send Failed\n");
}
else
{
puts("Data sent\n");
}
// and then close the socket
close(network_socket);
}
return 0;
}
The function sends data to the server and also receives data on the same connection. Now my problem is that the recv() function call always fails with an error code of 104 even when the server has sent data back to the client socket.
Below is the code for the server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
/*
Input Data using commands
Send data to the server
The server writes the data to a text file
Database connection in C
*/
struct patient_data
{
char patient_name[256];
char patient_date[256];
char patient_category[256];
char patient_gender[10];
} s_results;
int main()
{
// create the server socket
int server_socket;
server_socket = socket(AF_INET,SOCK_STREAM,0);
// define the server address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY;
// bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr*) &server_address,sizeof(server_address));
listen(server_socket,100);
int client_socket;
client_socket = accept(server_socket,NULL,NULL);
struct data
{
int type;
char name[100];
char date_of_identificaton[20];
char category[10];
char gender[5];
} response;
// receive data from server
recv(client_socket,&response,sizeof(response),0);
if(response.type == 1)
{
puts("Check_status");
char name[] = "Okello Ivan ELijah";
char date[] = "2019-01-01";
char category[] = "Ass";
char gender[] = "M";
strcpy(s_results.patient_name,name);
strcpy(s_results.patient_date,date);
strcpy(s_results.patient_category,category);
strcpy(s_results.patient_gender,gender);
send(server_socket,&s_results,sizeof(s_results),0);
puts("Data sent\n");
printf("%s\n%d\n%s\n",response.name,response.type,response.gender);
}
else
{
puts("Data not sent");
}
// close the socket
close(server_socket);
return 0;
}
The server also does not execute the if statement fully. It just executes the first statement of the if else statement and doesn't execute the others. What could be the problem??
Please help me with this anybody
... even when the server has sent data back to the client socket.
Actually, your server does not send data to the client. You probably intended it with this line in the server:
send(server_socket,&s_results,sizeof(s_results),0);
Only, this is using server_socket which is the listener socket. Instead it should have used client_socket, which is the connected socket. Note that if you would have checked the send call for errors you would have realized that the send has failed too. Thus, better check for errors on all places.
I am implementing a server/client app for educational purposes. My server opens a socket and polls it for connections. If a connection is available it accepts it and sends some data over. Then it waits for input and sends some data back again.
When implementing the client side, I tried writing to the socket right away, but that did not work. I had to receive first what the server told me and then send it some data. Then wait to receive again.
This does not seem a good solution and since this is an educational project I was wondering how I would go about making it abstract (i.e. not care about how many times the server would send me something and I would send it something back.)
So far I have tried looping to receive the server's input but without success. The server writes twice to the socket, so the client must read twice before trying to send its own message. If I read a third time the read blocks (which I think is the normal behaviour).
I tried using poll on the socket from the client's side to watch for POLLOUT events, but it does not seem to work.
int connect(){
unsigned int backlog = 10;
/*
struct sockaddr_in {
short sin_family; // e.g. AF_INET
unsigned short sin_port; // e.g. htons(3490)
struct in_addr sin_addr; // see struct in_addr, below
char sin_zero[8]; // zero this if you want to
};
struct in_addr {
unsigned long s_addr; // load with inet_aton()
};
*/
struct sockaddr_in server{};
//Create socket
listeningSocket = socket(AF_INET, SOCK_STREAM, 0);
if (listeningSocket == -1) {
spdlog::critical("Could not create socket");
}
spdlog::debug("Socket created.");
//Prepare the socket for incoming connections
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PortNumber); // NOLINT(hicpp-signed-bitwise)
if (bind(listeningSocket, (const struct sockaddr *) &server, sizeof(sockaddr_in)) < 0) {
spdlog::critical("bind failed. Error");
exit(-1);
}
spdlog::debug("Bind succeeded\n");
if (!listen(listeningSocket, static_cast<int>(backlog))) {
return listeningSocket;
}
return -1;
}
Handle the message
void* sendMessage(){
//Get the socket descriptor
int sock = socket;
int read_size;
const char *message;
char client_message[200];
//Send some messages to the client
message = "Greetings! I am your connection handler\n";
write(sock, message, strlen(message));
message = "Now type something and i shall apply the caesar cipher to it \n";
write(sock, message, strlen(message));
//Receive a message from client
while ((read_size = recv(sock, client_message, 200, 0)) > 0) {
//end of string marker
client_message[read_size] = '\0';
std::string temp(client_message);
temp = cipher->operate(temp);
//Send the message back to client
write(sock, temp.c_str(), strlen(temp.c_str()));
//clear the message buffer
memset(client_message, 0, 200);
}
if (read_size == 0) {
spdlog::debug("Client disconnected");
fflush(stdout);
} else if (read_size == -1) {
spdlog::error("recv failed: {}",errno);
}
return nullptr;
}
As for the client side:
//Connect to the server
void connect()
{
struct hostent *he;
struct sockaddr_in their_addr{}; /* connector's address information */
if ((he=gethostbyname(mHost.c_str())) == nullptr) { /* get the host info */
spdlog::error("gethostbyname");
}
if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
spdlog::error("socket");
exit(1);
}
their_addr.sin_family = AF_INET; /* host byte order */
their_addr.sin_port = htons(mPort); /* short, network byte order */ //NOLINT
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
if (connect(mSocket, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
spdlog::error("connect");
exit(1);
}
}
}
And try to send the message:
void sendMessage(){
#define MAX 100
if (!sockfd) {
sockfd = mSocket;
spdlog::info("Setting socket to {}", sockfd);
}
char buff[MAX];
struct pollfd fds[1];
fds[0].fd=sockfd;
while (( recv(sockfd, buff, 200, 0)) > 0) {
printf("From Server : %s", buff);
bzero(buff, sizeof(buff));
}
strcpy(buff, "PAPARI");
write(sockfd, buff, sizeof(buff));
bzero(buff, sizeof(buff));
read(sockfd, buff, sizeof(buff));
printf("From Server : %s", buff);
close(sockfd);
}
This will block after the two messages from the server are received by the client.
I am new to Network Programming and the first program we were supposed to do in our lab was a program where two systems, client and the server send messages to each other. My program has no compiler errors, but whenever a message is sent over the network, it is not being displayed properly on the other end. Instead an unreadable box is being displayed (I think a garbage string is being printed but don't know why).
View the screenshot here
The codes:
client.c
int main()
{
char server_message[256]="You have reached the server!!\n";
//create a socket
int nw_socket;
nw_socket=socket(AF_INET,SOCK_STREAM,0);
//specify address for socket
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9999);
server_address.sin_addr.s_addr = INADDR_ANY;
//establish a connection
int connection_status = connect(nw_socket, (struct sockaddr *) & server_address, sizeof(server_address));
//check for errors
if(connection_status==-1)
{
perror("There was a problem initiating the connection.\n");
}
else
{
printf("The connection was successful.\n");
}
int send_val = send(nw_socket,server_message,sizeof(server_message),0);
if(send_val==-1)
perror("\nError while sending: ");
//receive data
char data[256];
int recv_val=recv(nw_socket,data,sizeof(data),0);
if(recv_val==-1)
perror("\nError while receiving: ");
printf("The server's response was: %s\n",data );
//close the socket
close(nw_socket);
return 0;
}
server.c
int main()
{
char server_message[256]="You have reached the server!!\n";
//create a new socket
int server_socket=socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_connection;
server_connection.sin_family=AF_INET;
server_connection.sin_port=htons(9999);
server_connection.sin_addr.s_addr=INADDR_ANY;
int bind_val=bind(server_socket, (struct sockaddr *) & server_connection, sizeof(server_connection));
if(bind_val==-1)
perror("\nError while binding: ");
listen(server_socket,6);
int client_socket=accept(server_socket, NULL, NULL);
if(client_socket==-1)
perror("\nError while accepting: ");
int send_val= send(server_socket,server_message,sizeof(server_message),0);
if(send_val==-1)
perror("\nError while sending: ");
char data[256];
recv(server_socket,data,sizeof(data),0);
close(server_socket);
return 0;
}
How do I fix this? Thanks in advance.
You are using the listening socket when sending a message in the server:
int send_val= send(server_socket,server_message,sizeof(server_message),0);
You should be using the socket connected to the client:
int send_val = send(client_socket,server_message,sizeof(server_message),0);
I am writing a Server program serving to Multiple client(max 5). As any client connects to server, server stores the descriptor into an array and checks for any activity in those descriptors via Select system call. But, it is only reading from any 2 clients only and rest client requests are not being served at all. Here is a code for Server
#define NUM_CLIENT 5
void main(int argc,char** argv)
{
int master_sock, newSocket, err;
struct sockaddr_in Server_addr, Client_addr;
char buf[100];
int i=0;
int activity;
//socket descriptors for select
fd_set readfd;
int client_fd[NUM_CLIENT]={-1,-1,-1,-1,-1};
//Socket creation
master_sock= socket(AF_INET,SOCK_STREAM,0);
if(master_sock<0){
perror("socket");
return;
}
//structure filling for listening to the port
Server_addr.sin_family = AF_INET;
Server_addr.sin_port = htons(atoi(argv[1]));
Server_addr.sin_addr.s_addr = INADDR_ANY;
//Binding to the Address and port filled in structure
err = bind(master_sock,(struct sockaddr*)&Server_addr,sizeof(Server_addr));
if(err<0){
perror("socket");
return;
}
printf("\nlistening to port");
err = listen(master_sock,NUM_CLIENT); //to inform, the willlingness to accept connections.
if(err<0){
perror("Listen");
return;
}
printf("\nAccepting connection");
while(1)
{
//Select modifies the objects in structure for any activity,
// So we need to load them again.
FD_ZERO(&readfd); //clearing the readfd list
FD_SET(master_sock,&readfd); //adding the descriptor for select to listen
for(i=0;i<NUM_CLIENT;i++){
if(client_fd[i] != -1){
FD_SET(client_fd[i],&readfd); //Add socket to the list
}
}
//Descriptors loaded..
//start Select operation....
activity = select(NUM_CLIENT+1,&readfd,NULL,NULL,NULL); //wait here until any activiy occurs
if(activity < 0){
perror("Select");break;
}
printf("\nactivity happened in socket...");
//If activity related to master socket i.e. New client is trying to connect.
if( FD_ISSET(master_sock,&readfd) ) {
printf("\nactivity in master socket...");
int len = sizeof(Client_addr);
//Accept the connection
newSocket = accept(master_sock, (struct sockaddr*)&Client_addr ,&len); //blocking call
if(newSocket<0){
perror("accept");return;
}
printf("\nNew connection accepted");
// puts("Receiving data");
if( recv(newSocket,buf,100,0) > 0 ) //blocking call
printf("\n%s",buf);
else
strcpy(buf,"hey");
// puts("Sending data");
if( send(newSocket,buf,strlen(buf),0) < 0 )
perror("send");
//creating client database of descriptors
for(i=0;i<NUM_CLIENT;i++){
printf("\nfd[%d] = %d\n",i,client_fd[i]);
if(client_fd[i] == -1){
client_fd[i]= newSocket;
//FD_SET(newSocket,&readfd); //Add socket to the list
//printf("\nfd[%d] = %d\n",i,client_fd[i]);
break;
}
}
}
//If activity(read or write) in other sockets, check it out
printf("\nChecking Activity in Other File Descriptors\n");
for(i=0;i<NUM_CLIENT;i++){
if(FD_ISSET(client_fd[i],&readfd)){
printf("\nactivity in client %d ...",i);
// puts("Receiving data");
if( recv(client_fd[i],buf,100,0) > 0 ) //blocking call
puts(buf);
else
strcpy(buf,"hello");
// puts("Sending data");
if( send(client_fd[i],buf,strlen(buf)+1,0) == -1 )
perror("send");
//printf("\n%s",buf);
}
}
}
}
And every client sends and receive data after sleeping for given time(provided via command line). Example: client1 5sec ,client2 4sec and so on...
The code for client is :
void main(int argc, char** argv)
{
int fd, err;
char buf[100],buf2[100];
struct sockaddr_in server;
fd = socket(AF_INET,SOCK_STREAM,0);
if(fd<0){
perror("socket");return;
}
I2A(buf,getpid()); //Integer to array conversion, returns array
strcat(buf,"Hello");
printf("%s\n",buf);
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1])); //Host to network
server.sin_addr.s_addr = inet_addr("127.0.0.1");
printf("Connecting with server\n");
if( connect(fd, (struct sockaddr*)&server,sizeof(server) ) < 0) {
perror("connect");return;
}
printf("Connected with server\n");
while(1){
// printf("Sending data\n");
if( send(fd,buf,20,0) < 0)
perror("send");
// printf("Receiving data\n");
if( recv(fd,buf2,sizeof(buf2),0) >0 )
printf("%s\n",buf2);
sleep(atoi(argv[2]));
}
Thanks in advance.
This line is wrong:
activity = select(NUM_CLIENT+1,&readfd,NULL,NULL,NULL); //wait here until any activiy occurs
The first argument to select() should not be NUM_CLIENT+1, but rather the maximum file descriptor value (across all of the file descriptor values that you called FD_SET() on)), plus one.
My mini project is on implementing a c socket program where multiple clients send files to two or three servers. i have implemented these. but for handling the client request i need to create a child process is it? how can i do that . like have to handle the request separately.please anybody guide me to do it.
server:
int main()
{
int sockfd, new_sockfd,x1,x2,log,n;
int server_len, client_len,len;
int cont,fh,cont2;
int result1;
struct sockaddr_in serveraddress;
struct sockaddr_in address;
struct sockaddr_in client_address;
FILE *ia_address;
char *fname = "/home/shishira/Desktop/packet_capture/info_agent_report.txt";
int buffsize=1024;
char buffer1[1024];
char buffer[1024];
char clntName[INET_ADDRSTRLEN];
if((sockfd = socket(AF_INET,SOCK_STREAM,0))>0)
printf("\n Socket was created\n");
/* Name the socket. */
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_port = ntohs(9734);
server_len = sizeof(address);
bind(sockfd, (struct sockaddr *)&address, server_len);
/* Create a connection queue and wait INFO_AGENT_REPORTS */
listen(sockfd, 5);
while(1)
{
char ch;
printf("\n\n Task agent waiting...\n");
/* Accept a connection to collect report from INFO_AGENT */
client_len = sizeof(client_address);
new_sockfd = accept(sockfd,(struct sockaddr *)&client_address, &client_len);
if (new_sockfd==-1) { perror("Connection Not Accepted!!"); return(1);}
else
{
printf("\n Information agent is connected\n");
if(inet_ntop(AF_INET,&client_address.sin_addr.s_addr,clntName,sizeof(clntName))!=NULL)
{
ia_address = fopen("info_agent_report.txt","a+");
fprintf(ia_address,"\nFrom InformationAgent:%s\n",clntName);
fclose(ia_address);
}
printf("\n Task agent received the contents and saved it in 'info_agent_report' file");
log=open("info_agent_report.txt",O_CREAT|O_RDWR|O_APPEND,0777);
if(log==-1)
{
perror("cannot open info_agent_report file\n");
return(1);
}
do
{
x1=read(new_sockfd, buffer1, 1024);
x2=write(log,buffer1,x1);
}
while (x1>0);
close(log);
close(new_sockfd);
}
/*this is to connect to other server */
/* connect socket to the interface server's socket. */
int interface_sockfd = socket(AF_INET,SOCK_STREAM,0);
serveraddress.sin_family = AF_INET;
serveraddress.sin_addr.s_addr = inet_addr("127.0.0.1");
serveraddress.sin_port = 9735;
len = sizeof(serveraddress);
//len=sizeof(address);
if((result1 = connect(interface_sockfd, (struct sockaddr *)&serveraddress, len))==0)
printf("\n Connecting to the Interface server\n");
if(result1 == -1)
{
perror(" Not able to connect to Interface Server!!!!\n");
}
fh = open(fname , O_RDONLY);
if(fh==-1)
{
perror(" INFO_AGENT_REPORT File is Not Opened!!\n");
return(1);
}
do
{
cont=read(fh, buffer, buffsize);
cont2=write(interface_sockfd,buffer,cont);
}
while (cont==1024);
close(fh);
printf("\n Task agent has sent 'info_agent_report' file to the Interface Server\n\n");
close(interface_sockfd);
}
}
getnameinfo() is more new-style.
You use it like
char clntName[INET6_ADDRSTRLEN];
char portName[6]; // I wonder if there is no appropriate constant...
if(getnameinfo(&client_address,sizeof client_address,clntName,sizeof(clntName),NULL,0,NI_NUMERICHOST|NI_NUMERICSERV|NI_NUMERICSCOPE)==0){
printf("Client = %s/%s\n",clntName,portName);
} else {
printf("Unable to get address\n");
}
Once you have done so, you won't have any difficulties mixing IPv4 and IPv6 calls.
Here is how : ( put this after accept ):
char clntName[INET_ADDRSTRLEN];
FILE *output;
if(inet_ntop(AF_INET,&client_address.sin_addr.s_addr,clntName,sizeof(clntName))!=NULL){
output = fopen("output.txt","a+");
fprintf(output,"%s%c%d",clntName,'/',ntohs(client_address.sin_port));
fclose(output);
} else {
printf("Unable to get address\n"); // i just fixed this to printf .. i had it as print before
}