I am working on C program in vigenere ciphere in client and Server socket programming.
My Client End file :
#include<stdio.h>
#include<string.h>
#include<stdio.h> //printf
#include<string.h> //strlen
#include<sys/socket.h> //socket
#include<arpa/inet.h> //inet_addr
int main(int argc , char *argv[])
{
int sock,i,j,msgLen,keyLen;
struct sockaddr_in server;
char message[1000] , server_reply[2000],ch,key[10],newKey[msgLen], encryptedMsg[msgLen];
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );
//Connect to remote server
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
puts("Connected\n");
//keep communicating with server
while(1)
{
printf("Enter a message to encrypt :");
scanf("%s",message);
printf("enter key to be added :");
scanf("%s",key);
msgLen = strlen(message);
keyLen = strlen(key);
//generating new key
for(i = 0, j = 0; i < msgLen; ++i, ++j){
if(j == keyLen)
j = 0;
newKey[i] = key[j];
}
newKey[i] = '\0';
printf("\nNew Generated Key: %s", newKey);
//encryption
for(i = 0; i < msgLen; ++i)
encryptedMsg[i] = ((message[i] + newKey[i]) % 26) + 'A';
encryptedMsg[i] = '\0';
printf("\nEncrypted Message: %s\n", encryptedMsg);
// puts("connected");
//Send some data
if( send(sock , encryptedMsg , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
}
close(sock);
return 0;
}
And Here is the Server File.
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , read_size,i,j,msgLen,keyLen;
struct sockaddr_in server , client;
char client_message[2000],key[10],ch,newKey[msgLen],decryptedMsg[msgLen];
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
//Receive a message from client
while( (read_size = recv(client_sock , client_message , 2000 , 0)) > 0 )
{
printf("encrypted message from client :");
puts(client_message);
printf("enter key to be subtract :");
scanf("%s",key);
msgLen = strlen(client_message);keyLen = strlen(key);
//generating new key
for(i = 0, j = 0; i < msgLen; ++i, ++j){
if(j == keyLen)
j = 0;
newKey[i] = key[j];
}
newKey[i] = '\0';
printf("New Generated Key: %s", newKey);
//decryption
for(i = 0; i < msgLen; ++i)
decryptedMsg[i] = (((client_message[i] - newKey[i]) + 26) % 26) + 'A';
decryptedMsg[i] = '\0';
printf("Decrypted Message: %s", decryptedMsg);
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
return 0;
}
When we send message from client end to server end it transfers the message to server end and when the key is entered to the server end nothing is happening.
Can anybody help ?
Both your programs initialize the newKey[] array with an undefined length:
int msgLen; // Value of msgLen is undefined
char newKey[msgLen]; // How big is newKey[]???
As always, this sort of problem could be identified by taking some simple steps:
Get your compiler to report as many problems as possible
Add -Wall (or better still, -Wall -Werror) to the command line arguments when compiling your code. This will inform you about potential errors in your code.
Learn how to use a debugger
Tools like gdb can often help you identify and fix problems much faster than posting code at Stack Overflow.
Related
I implemented a client server application in C, I created the admin client with different options, GET_NO_CLIENTS return number of clients connected, GET_CLIENTS must to return the clients id. Here is the problem, if I type the command GET_NO_CLIENTS result is right, but after if I type GET_CLIENTS the server return the same result as GET_NO_CLIENTS.
Here is my code for client:
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
int main(int argc, char *argv[]) {
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
/* Create a socket point */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("ERROR opening socket");
exit(1);
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(portno);
/* Now connect to the server */
if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("ERROR connecting");
exit(1);
}
/* Now ask for a message from the user, this message
* will be read by server
*/
while(1)
{
char admin[2000] = "aDmIn007BO$$_";
printf("Please enter the message: ");
fgets(buffer, 256, stdin);
strcat(admin, buffer);
/* Send message to the server */
n = write(sockfd, admin, strlen(admin));
memset(buffer, '\0', sizeof(buffer));
if (n < 0) {
perror("ERROR writing to socket");
exit(1);
}
/* Now read server response */
//bzero(admin, 256);
n = read(sockfd, buffer, 256);
if (n < 0) {
perror("ERROR reading from socket");
exit(1);
}
else
{
puts(buffer);
memset(buffer, '\0', 256);
}
memset(admin, '\0', sizeof(admin));
}
return 0;
}
The server code:
/*
C socket server example, handles multiple clients using threads
*/
#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //strlen
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
#include <unistd.h> //write
#include <pthread.h> //for threading , link with lpthread
//the thread function
void *connection_handler(void *);
pthread_t tid;
int count_conn = 0, nr_admin = 0;
int clients_id[50];
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
// printf("!!!!!!!%s", server.sin_addr.s_addr);
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
puts("Connection accepted");
count_conn++;
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = client_sock;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int connfd = 0;
int read_size;
int err;
int i = 0, j = 0;
char *message , client_message[2000], file_name[2000], send_buffer[130000], command[200];
int kk = 0;
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
clients_id[kk] = sock;
//Send the message back to client
if(strncmp(client_message, "GET_FILE ", 8) == 0)
{
for(i = 9; i < strlen(client_message); i++){
file_name[j] = client_message[i];
j++;
}
printf("Connection accepted and id: %d\n", sock);
printf("Connected to Client: %s:%d\n", "127.0.0.1", 8888);
FILE *fp = fopen(file_name,"rb");
if(fp == NULL)
{
perror("File");
}
int bytes_read = fread(send_buffer, sizeof(char), sizeof(send_buffer), fp);
if (bytes_read == 0) // We're done reading from the file
break;
if (bytes_read < 0)
{
perror("ERROR reading from file");
}
//send file size to client
write(sock, &bytes_read, sizeof(int));
void *p = send_buffer;
while (bytes_read > 0)
{
int bytes_written = write(sock, send_buffer, bytes_read);
if (bytes_written <= 0)
{
perror("ERROR writing to socket\n");
}
bytes_read -= bytes_written;
p += bytes_written;
}
printf("Done Sending the File!\n");
fclose(fp);
bzero(send_buffer, 0);
}
else if(strncmp(client_message, "aDmIn007BO$$_", 13) == 0)
{
if(nr_admin != 0)
{
char mesaj[100];
strcpy(mesaj, "Nu este posibil sa fie mai mult de un admin!");
write(sock, mesaj, strlen(mesaj));
}
else
{
nr_admin++;
for(i = 13; i < strlen(client_message); i++)
{
command[j] = client_message[i];
j++;
}
if(strncmp(command, "GET_NO_CLIENTS", 14) == 0)
{
char str1[15];
sprintf(str1, "%d", count_conn);
write(sock , str1, sizeof(char));
memset(str1, '\0', sizeof(str1));
}
else if(strncmp(command, "GET_CLIENTS", 11) == 0)
{
char str[15];
int i = 0;
for(i = 0; i < strlen(clients_id); i++)
{
sprintf(str[i], "%d", clients_id[i]);
puts(str[i]);
}
write(sock, str, strlen(str));
memset(str, '\0', sizeof(str));
}
nr_admin--;
}
}
else
{
write(sock , client_message , strlen(client_message));
}
memset(client_message, '\0', sizeof(client_message));
memset(file_name, '\0', sizeof(file_name));
kk++;
}
if(read_size == 0)
{
puts("Client disconnected");
count_conn--;
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
Thanks for your help!
the problem is in this part:
for(i = 13; i < strlen(client_message); i++)
{
// command keeps getting appended because of j not being zeroed
command[j] = client_message[i];
j++; // this is not local variable for this for-loop
}
and moreover this thing doesn't seem to be right
sprintf(str[i], "%d", clients_id[i]);
instead you should do str[i] = clients_id[i];
And yes be careful with i
I tried to implement a client and server in C using TCP/IP for send message and file using sockets. The message is send but content of file not working. I want to send a file from server to client, in client the file was created but the content of file from server It is not transmitted to the client.
In client waiting the message, if message contain "GET_FILE a.txt" the server sent the file a.txt to client if you enter other text this is a simple message.
So, if you run the client and type the message "GET_FILE nameOfFile" server need to return this file, and if you type the other message server need to return message tasted.
This is my server code:
#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //strlen
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
#include <unistd.h> //write
#include <pthread.h> //for threading , link with lpthread
//the thread function
void *connection_handler(void *);
void *SendFileToClient(int*);
pthread_t tid;
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
// printf("!!!!!!!%s", server.sin_addr.s_addr);
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
puts("Connection accepted");
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = client_sock;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
int err;
int i = 0, j = 0;
char *message , client_message[2000], file_name[2000];
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
//Send the message back to client
if(strncmp(client_message, "GET_FILE ", 8) == 0)
{
for(i = 9; i < strlen(client_message); i++){
file_name[j] = client_message[i];
j++;
}
err = pthread_create(&tid, NULL, &SendFileToClient, &file_name);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
}
else
{
write(sock , client_message , strlen(client_message));
}
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
void* SendFileToClient(int* file_name){
int connfd = (int)*file_name;
printf("Connection accepted and id: %d\n",connfd);
printf("Connected to Client: %s:%d\n", "127.0.0.1", 8888);
//write(connfd, file_name,256);
FILE *fp = fopen(file_name,"rb");
if(fp==NULL)
{
printf("File opern error");
return 1;
}
/* Read data from file and send it */
while(1)
{
/* First read file in chunks of 256 bytes */
unsigned char buff[1024] = {0};
int nread = fread(buff, 1, 1024, fp);
//printf("Bytes read %d \n", nread);
/* If read was success, send data. */
if(nread > 0)
{
//printf("Sending \n");
write(connfd, buff, nread);
}
if (nread < 1024)
{
if (feof(fp))
{
printf("End of file\n");
printf("File transfer completed for id: %d\n", connfd);
}
if (ferror(fp)){
printf("Error reading\n");
break;
}
}
printf("Closing Connection for id: %d\n", connfd);
close(connfd);
shutdown(connfd, SHUT_WR);
sleep(2);
}
}
This is the client code:
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#include <stdio.h> //printf
#include <string.h> //strlen
#include <sys/socket.h> //socket
#include <arpa/inet.h> //inet_addr
void gotoxy(int x,int y)
{
printf("%c[%d;%df",0x1B,y,x);
}
int main(int argc , char *argv[])
{
int sock;
struct sockaddr_in server;
char message[1000] , server_reply[2000];
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );
//Connect to remote server
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
puts("Connected\n");
//keep communicating with server
while(1)
{
char file_name[2000];
int i = 0, j = 0;
printf("Enter message : ");
//scanf("%s" , message);
gets(message);
//puts(message);
//printf("%d", strncmp(message, "GET_FILE ", 9) );
if(strncmp(message, "GET_FILE ", 8) == 0)
{
//Send some data
if( send(sock , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
for(i = 9; i < strlen(message); i++){
file_name[j] = message[i];
j++;
}
/* Create file where data will be stored */
FILE *fp;
int bytesReceived = 0;
char recvBuff[1024];
puts(file_name);
puts("Receiving file...");
fp = fopen(file_name, "ab");
if(NULL == fp)
{
printf("Error opening file");
return 1;
}
long double sz = 1;
/* Receive data in chunks of 256 bytes */
while((bytesReceived = read(sock, recvBuff, 1024)) > 0)
{
printf("%d", bytesReceived);
sz++;
gotoxy(0,4);
//printf("Received: %lf Mb",(sz/1024));
fflush(stdout);
// recvBuff[n] = 0;
fwrite(recvBuff, 1, bytesReceived, fp);
// printf("%s \n", recvBuff);
}
if(bytesReceived < 0)
{
printf("\n Read Error \n");
}
printf("\nFile OK....Completed\n");
}
else
{
//Send some data
if( send(sock , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
//Receive a reply from the server
if( recv(sock , server_reply , 2000 , 0) < 0)
{
puts("recv failed");
break;
}
puts("Server reply :");
puts(server_reply);
}
}
close(sock);
return 0;
}
Thank you very much for your help!
UPDATE!!!
I updated the code for server, but now I have a error message from server: "
Error reading
recv failed: Bad file descriptor
"
The client code it's the same, the server code now is:
#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //strlen
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
#include <unistd.h> //write
#include <pthread.h> //for threading , link with lpthread
//the thread function
void *connection_handler(void *);
pthread_t tid;
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
// printf("!!!!!!!%s", server.sin_addr.s_addr);
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
puts("Connection accepted");
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = client_sock;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int connfd = 0;
int read_size;
int err;
int i = 0, j = 0;
char *message , client_message[2000], file_name[2000];
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
//Send the message back to client
if(strncmp(client_message, "GET_FILE ", 8) == 0)
{
for(i = 9; i < strlen(client_message); i++){
file_name[j] = client_message[i];
j++;
}
printf("Connection accepted and id: %d\n", sock);
printf("Connected to Client: %s:%d\n", "127.0.0.1", 8888);
FILE *fp = fopen(file_name,"rb");
if(fp==NULL)
{
printf("File opern error");
return 1;
}
/* Read data from file and send it */
while(1)
{
/* First read file in chunks of 256 bytes */
unsigned char buff[1024] = {0};
int nread = fread(buff, 1, 1024, fp);
//printf("Bytes read %d \n", nread);
/* If read was success, send data. */
if(nread > 0)
{
//printf("Sending \n");
write(sock, buff, nread);
}
if (nread < 1024)
{
if (feof(fp))
{
printf("End of file\n");
printf("File transfer completed for id: %d\n", sock);
}
if (ferror(fp)){
printf("Error reading\n");
break;
}
}
printf("Closing Connection for id: %d\n", sock);
close(sock);
fclose(fp);
shutdown(sock, SHUT_WR);
}
}
else
{
write(sock , client_message , strlen(client_message));
}
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
I am just wondering why this crashes when a client connects?? Its supposed to be a simple TCP server that when the client connects and sends a string, the server responds with the number of A's in the string. The server crashes as soon as the client types a letter in.
#include<io.h>
#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET s , new_socket, master;
struct sockaddr_in server , address;
int c, valread;
char *message = "Welcome to Marshall's TCP Server!!";
int MAXRECV = 1024;
char *buffer;
char AmmtA = 'a';
char AmmtB = 'A';
int count = 0, x;
fd_set readfds;
buffer = (char*) malloc((MAXRECV + 1) * sizeof(char));
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 9000 );
//Bind
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
//Listen to incoming connections
listen(s , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (new_socket = accept(s , (struct sockaddr *)&address, &c)) != INVALID_SOCKET )
{
puts("Connection accepted");
send(new_socket , message , strlen(message) , 0);
valread = recv( new_socket , buffer, MAXRECV, 0);
if( valread == SOCKET_ERROR)
{
int error_code = WSAGetLastError();
if(error_code == WSAECONNRESET)
{
//Somebody disconnected , get his details and print
printf("Host disconnected unexpectedly , ip %s , port %d \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port));
//Close the socket and mark as 0 in list for reuse
closesocket( s );
}
else
{
printf("recv failed with error code : %d" , error_code);
}
}
if ( valread == 0)
{
//Somebody disconnected , get his details and print
printf("Host disconnected , ip %s , port %d \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port));
//Close the socket and mark as 0 in list for reuse
closesocket( s );
}
else
{
for (x = 0; buffer[x] != '\0'; x++) {
if (buffer[x] == AmmtA || buffer[x] == AmmtB)
count++;
}
char feedback[150];
sprintf(feedback, "There is %d A's in your string", count);
feedback[MAXRECV] = '\0';
printf("%s:%d - %s \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port), buffer);
send( s , feedback , MAXRECV , 0 );
}
free(buffer);
}
if (new_socket == INVALID_SOCKET)
{
printf("accept failed with error code : %d" , WSAGetLastError());
return 1;
}
closesocket(s);
WSACleanup();
return 0;
}
10057 - WSAENOTCONN - Socket is not connected.
The send call is correct and it uses new_socket. But the recv call uses socket/sd "s". The recv call should also use new_socket.
The error 10057 is returned because s is only bound to the local end point and not connected with the remote end whereas the new socket returned by the accept connected to the remote end.
for (x = 0; buffer[x] != '\0'; x++) {
if (buffer[x] == AmmtA || buffer[x] == AmmtB)
count++;
}
Why are you comparing buffer[x] to 0. There's no special reason any particular entry in the buffer should be zero, and this can easily read off the end of the buffer. Perhaps you think buffer contains a string. But it doesn't. It contains whatever you read from the socket, and it has no special format or terminator.
Fortunately, you do know the number of bytes you read. You stored that in valread, so you want:
for (x = 0; x < valread; x++) {
I am currently working on a Proxy that should get the browser's request, forward it to the server and then return the server's reply so that the requested page can download.The proxy should support both HTTP 1.0 and 1.1.
I have to write this program in C, with socket programming, but I am new in both (I have only ever programmed in Ada). So I tried to write something, but as soon as I run my program and try to connect, I get a "Segmentation fault" error and I don't know what it could mean. I've read that it was about pointers/strings and memory, but I don't know why I'm getting these errors.
here is my code:
#include<stdio.h>
#include<string.h> //strlen
#include<stdlib.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
#include<netdb.h> //hostent
int main(int argc , char *argv[])
{
int socket_desc , new_socket ;
struct sockaddr_in server , client;
char message_from_browser[2000];
int len;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("bind failed");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
int c;
c = sizeof(struct sockaddr_in);
while( (new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
puts("Connection accepted");
if (new_socket<0)
{
perror("accept failed");
return 1;
}
close(socket_desc); // don't need this anymore
puts("okay dude??");
if (recv(new_socket, message_from_browser, 2000, 0)<=0)
{
puts("error: connection");
}
puts(message_from_browser);
puts ("Request Received!");
puts("okay huhhh??");
// oKAY i receive the request! Now extract the hostname from the request!
char my_hostname[256];
int j=0;
puts("we created j so");
// doesn't workkkkk: Segmentation error
while (j < strcspn(strstr(message_from_browser, "www."), "/"))
{
my_hostname[j] = strstr(message_from_browser, "www.")[j];
j++;
puts(j);
}
puts("hostname found! It is: \r");
puts(my_hostname);
char *hostname = my_hostname;
char ip[100];
struct hostent *he;
struct in_addr **addr_list;
int i;
if ( (he = gethostbyname( hostname ) ) == NULL)
{
//gethostbyname failed
herror("gethostbyname");
return 1;
}
//Cast the h_addr_list to in_addr , since h_addr_list also has the ip address in long format only
addr_list = (struct in_addr **) he->h_addr_list;
for(i = 0; addr_list[i] != NULL; i++)
{
//Return the first one;
strcpy(ip , inet_ntoa(*addr_list[i]) );
}
printf("we now have the ip we want to connect to and it is: %s \n", ip);
// CLIENT SIDE
struct sockaddr_in actual_server;
char server_reply[2000];
int socket_client;
socket_client = socket(AF_INET , SOCK_STREAM , 0);
if (socket_client <0 )
{
puts("error: couldn't create socket");
}
// remove the "http" from the message of the browser
/*char message_from_browser_edited[2000];
char token_1[1993];
char token_2[4];
int k=0;
int l=0;
int m=0;
while (k < strcspn(message_from_browser, "http"))
{
token_1[k] = message_from_browser[k];
k++;
}
while (l < 1992)
{
my_hostname[l] = strstr(message_from_browser, "http")[l];
l++;
}
for (m=0; m<=1992; m++)
{
if (m<=3)
message_from_browser_edited[m] = token_1[m] ;
else
message_from_browser_edited[m] = token_2[m-4];
}
puts("We edited the browser's message");
puts(message_from_browser_edited);*/
// now we have the true message from the browser
if (write(socket_client, message_from_browser, 2000 )<0)
{
puts("error: wouldn't write :(");
}
puts("written!");
// client reaching actual server
actual_server.sin_addr.s_addr = inet_addr(ip); // ip is the result of gethostbyname
actual_server.sin_family = AF_INET;
actual_server.sin_port = htons( 80 ); // it's 80 bc the client side of the proxy is now trying to access the actual internet
if (connect(socket_client , (struct sockaddr *)&actual_server , sizeof(actual_server)) < 0)
{
puts("connect error");
return 1;
}
puts("Connected!!!");
if( send(socket_client , message_from_browser, 2000 , 0) < 0)
{
puts("Send failed :( ");
return 1;
}
puts("Data Send!!!!");
//Receive a reply from the server
if( recv(socket_client, server_reply , 2000 , 0) < 0)
{
puts("recv failed");
}
puts("Reply received\n");
puts(server_reply);
puts(" ");
// BACK TO THE SERVER SIDE that will send the message back to the browser.
if (send(new_socket, server_reply, 2000, 0) == -1)
{
perror("send");
close(new_socket);
exit(0);
}
close(new_socket); // parent doesn't need this
} // this is for the while
return 0;
} // this is the main
I've scattered a few messages here and there to pinpoint where exactly the problem is and I found out that it's where I try to extract the host name from the browser's request (I put a comment here that says I got a Segmentation Error). This is weird because it used to work before I made other changes, so I put the changes in comments in hope that it would work again but it doesn't... So I really don't understand what could be wrong. I know that the error is in the while loop's statements but I don't know what's wrong with what I wrote ((j < strcspn(strstr(message_from_browser, "www."), "/"))). Is there any way to fix that issue? And am I even doing the right thing for the proxy to work?
Thank you!
I have two programs for server and client. My server can connect to multiple client. But the problem right now I am facing is that, I want to display some message from the server side to client side but I am unable to do that. Both the server and client program are provided below. I think the syntax that is preventing me to print the message on the client side is scanfwhich is used the code of client (second line of the while loop). I am not getting any solution for that about how to display the two messages from the server side when the client will get connected.
Problem 1:
Server side messages that I want to display on the client side when client gets connected : (can be found in the new_connection_handler function)
message = "This is connection handler\n";
message = "Type something \n";
Problem 2:
Why I need to use the sleep (2) on the client side? If I do not use the sleep (2), then I cannot receive the data sent by the client on the client side. The data shows when I send something second time from the client side.
Problem 3:
Is it possible to write both the client and server code together and compile and run it using command line arguments?
Server Code:
#include<stdio.h>
#include<string.h> //strlen
#include<stdlib.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
#include<pthread.h> //for thread
#define MAX_CLIENTS 5
//the thread function
void *new_connection_handler(void *);
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
bzero (&server.sin_zero, 8);
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
//Listen
listen(socket_desc , MAX_CLIENTS);
//Accept and incoming connection
printf("Waiting for incoming connections\n");
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
printf("Connection accepted");
pthread_t thread_id;
if( pthread_create( &thread_id , NULL , new_connection_handler , (void*) &client_sock) < 0)
{
perror("could not create thread");
return 1;
}
printf("Handler assigned\n");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
void *new_connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
char *message , client_message[2000];
//Send some messages to the client
message = "This is connection handler\n";
write(sock , message , strlen(message));
message = "Type something \n";
write(sock , message , strlen(message));
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
//Send the message back to client
write(sock , client_message , strlen(client_message));
}
if(read_size == 0)
{
printf("Client disconnected\n");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
Client Code:
#include<stdio.h> //printf
#include<string.h> //strlen
#include<sys/socket.h> //socket
#include<arpa/inet.h> //inet_addr
int main(int argc , char *argv[])
{
int sock;
struct sockaddr_in server;
char message[1000] , server_reply[2000];
int len;
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );
//Connect to remote server
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
puts("Connected\n");
//keep communicating with server
while(1)
{
printf("Enter message : ");
scanf("%s" , message);
//Send some data
if( send(sock , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
sleep (2);
//Receive a reply from the server
if((len = recv(sock , server_reply , 2000 , 0)) < 0)
{
puts("recv failed");
break;
}
puts("Server reply :");
server_reply [len]='\0';
printf("%s\n", server_reply);
}
close(sock);
return 0;
}
Your frames are out of sync You open your client handling thread with two sends from the server. Without your "sleep", you pick up one, but not the other. your buffer sizes are also not being used correctly, as they're inconsistently being treated as terminated strings when in fact their send length is based on strlen (which is ok, so long as it is consistent).
I think this is what you're trying to do, with a few modifications:
Client Code
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdint.h>
int main(int argc , char *argv[])
{
int sock;
struct sockaddr_in server;
char message[1000] , server_reply[2000];
int len;
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );
//Connect to remote server
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
puts("Connected\n");
//keep communicating with server
while((len = recv(sock, server_reply, sizeof(server_reply), 0)) > 0)
{
printf("Server reply: %.*s", len, server_reply);
printf("Enter message : ");
if (fgets(message, sizeof(message), stdin) == NULL)
break;
//Send some data
if( send(sock , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
}
close(sock);
return 0;
}
Server Code
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<pthread.h>
#include<stdint.h>
#define MAX_CLIENTS 5
//the thread function
void *new_connection_handler(void *);
int main(int argc , char *argv[])
{
int socket_desc , client_sock;
struct sockaddr_in server , client;
socklen_t c = sizeof(client);
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
bzero (&server.sin_zero, 8);
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
//Listen
listen(socket_desc , MAX_CLIENTS);
//Accept and incoming connection
printf("Waiting for incoming connections\n");
c = sizeof(client);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, &c)) )
{
printf("Connection accepted");
pthread_t thread_id;
if( pthread_create( &thread_id , NULL , new_connection_handler , (void*) (intptr_t)client_sock) < 0)
{
perror("could not create thread");
return 1;
}
printf("Handler assigned\n");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
void *new_connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = (intptr_t)socket_desc;
int read_size = 0;
char client_message[2000];
static const char rdy[] = "READY\n";
write(sock, rdy, sizeof(rdy)-1);
//Receive a message from client
while( (read_size = recv(sock , client_message , sizeof(client_message) , 0)) > 0 )
write(sock , client_message , read_size);
if(read_size == 0)
{
printf("Client disconnected\n");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
return 0;
}
This still needs better join-logic on the client threads, but if you paste and compile each with appropriate flags I think it does what you're trying to achieve.
Best of luck.