My objective is to implement a simple data transfer from server to client. The problem is that the client is unable to read data from the server most of the time (it only works sometimes) even though the server says that the transfer was successful.
server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#define PORT 8080
void main() {
int sock = socket(AF_INET, SOCK_STREAM, 0), option = 1;
struct sockaddr_in address;
socklen_t addrlen = sizeof(address);
char buffer[1024] = {0};
char source_file[] = "<path>/something.txt";
char fname[] = "something.txt";
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
if(bind(sock, (struct sockaddr*) &address, sizeof(address)) == -1){
perror("Could not bind to address");
return;
}
if(listen(sock, 5) == -1) {
perror("Error while listening to connections");
return;
}
int new_socket = accept(sock, (struct sockaddr*) &address, &addrlen);
if(new_socket == -1){
perror("Error connecting to client");
exit(EXIT_FAILURE);
}
else printf("Connected to client\n");
// first send the filename
if(send(new_socket, fname, sizeof(fname), 0) == -1){
perror("Error while sending file");
return;
}
printf("Sending file %s\n\n", source_file);
FILE* f = fopen(source_file, "r");
// send the contents of the file
while(fgets(buffer, sizeof(buffer), f)){
printf("Sending %s", buffer);
if(send(new_socket, buffer, strlen(buffer), 0) == -1)
perror("Error while sending\n");
else printf("Successfully sent\n\n");
memset(buffer, 0, sizeof(buffer));
}
printf("File transfer complete\n");
fclose(f);
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080
void main() {
int sock = socket(AF_INET, SOCK_STREAM, 0);
long val;
struct sockaddr_in address;
char buffer[1024] = {0};
address.sin_family = AF_INET;
address.sin_port = htons(PORT);
if(inet_pton(AF_INET, "127.0.0.1", &address.sin_addr) == -1){
perror("Invalid IP value");
exit(EXIT_FAILURE);
}
if(connect(sock,(struct sockaddr*) &address, sizeof(address)) == -1){
perror("Connection Error");
exit(EXIT_FAILURE);
}
else printf("Connected to server\n");
// Get file name from server
if(read(sock, buffer, sizeof(buffer)) == -1){
perror("Could not read filename from server");
exit(EXIT_FAILURE);
}
printf("Receiving file %s\n", buffer);
FILE *f = fopen(buffer, "w");
// printf("%ld", read(sock, buffer, sizeof(buffer)));
while((val = read(sock, buffer, sizeof(buffer)))){
if (val == 0) break;
if (val == -1) {
perror("Error reading the content");
break;
}
printf("Read returned %ld\n", val);
printf("Received %s", buffer);
fputs(buffer, f);
memset(buffer, 0, sizeof(buffer));
}
printf("File transfer complete\n");
fclose(f);
}
Sample text file for data transfer
Hello there!
Nice to meet you.
This is a text file.
Bye Bye :)
Have a good day.
Execution from server side
$ cc ./server.c -o server
$ ./server
Connected to client
Sending file /home/username/Documents/something.txt
Sending Hello there!
Successfully sent
Sending Nice to meet you.
Successfully sent
Sending This is a text file.
Successfully sent
Sending Bye Bye :)
Successfully sent
Sending Have a good day.
Successfully sent
File transfer complete
This was the output I got from the server-side. This is weird because on client-side I didn't receive any message
$ cc ./client.c -o client
$ ./client
Connected to server
Receiving file something.txt
File transfer complete
The while loop in client side did not execute at all (because the data within buffer wasn't printed) and the read function did not return -1 otherwise a proper message would have been displayed.
This exact client code only works sometimes and other times it doesn't. What's the problem here?
Related
Although it seems to be correctly implemented, it keeps on returning me ERROR when I establish a connection using the loopback address(127.0.0.1).
In addition to a simple TCP Client/Server connection, I have added an additional case:
If the client tries to send data but finds the connection closed, it is closed too. I perform it by checking if received data is equal to 0 (recv).
Given error:
CLIENT:
Welcome to the Client mode
Please, enter the Server's IP Address and Port (eg. 192.128.192.0 1320)
127.0.0.1 2700
Connected to the server. Now you can send messages
Please, enter a message. Enter "FINISH" if you want to finish the connection
ECHO
client: connection closed ->: Success
(1 bytes)Closing the connection
SERVER:
Hello and welcome to the Server mode
Please, enter the Server's Port (eg. 1320)
2700
Server socket successfully configured
Server listening [Clients allowed: 5]
server: accept error: Bad address
Client implementation:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
/**
struct sockaddr{
uint8_t sa_len; // struct length
sa_family_t sa_family; //protocol family: AF_XXX
char sa_data[8]; //socket addr
}
*/
//void notConnected();
int main(){
struct sockaddr_in serv_addr; //port + ip_addr
int my_socket, tcp_port;
char serv_host_addr[30];
char buffer[1024], inbuff[1024];
int io_buffer;
printf("Welcome to the Client mode\n");
//CONFIGURING THE CONNECTION
my_socket = socket(AF_INET, SOCK_STREAM, 0);//(2)
if(my_socket < 0){
perror("client: socket() error ->");
exit(EXIT_FAILURE);
}
bzero(&serv_addr, sizeof(serv_addr));//(4)
printf("Please, enter the Server's IP Address and Port (eg. 192.128.192.0 1320) \n");
scanf("%s %d", serv_host_addr, &tcp_port);//(1)
serv_addr.sin_family = AF_INET ;
serv_addr.sin_port = htons(tcp_port);
if(inet_pton(AF_INET,serv_host_addr,&serv_addr.sin_addr) < 1){
perror("client: inet_pton() error ->");
exit(EXIT_FAILURE);
}
if((connect(my_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr) )) < 0)//(5)
{
perror("client: connect() error ->");
exit(EXIT_FAILURE);
}
//ONCE CONNECTED, START THE SENDING/RECEIVING
printf("Connected to the server. Now you can send messages\n");
bzero(&buffer, sizeof(buffer));
while(strcmp(buffer, "OK\n") != 0){
printf("Please, enter a message. Enter \"FINISH\" if you want to finish the connection\n");//(3)
bzero(&buffer, sizeof(buffer));
fgets(buffer, sizeof(buffer), stdin);
io_buffer = send(my_socket, buffer, strlen(buffer),0);//(6)
if(io_buffer < 0){
perror("client: send() error ->");
exit(EXIT_FAILURE);
}
printf("ECHO %s (%d bytes)", buffer, io_buffer);
//RECEIVE AND CHECK IF CONNECTION HAS BEEN CLOSED
io_buffer = recv(my_socket, buffer, sizeof(buffer),0);
if(io_buffer < 0){
perror("client: recv() error ->");
exit(EXIT_FAILURE);
}
else if(io_buffer == 0){ //THIS IS SERVER IS CLOSED
perror("client: connection closed ->");
break;
}
printf("ECHO %s (%d bytes)", buffer, io_buffer);
}
printf("Closing the connection \n");
for(int i=0; i < 5; i++){
printf(". ");
usleep(500000);
}
close(my_socket);
}
Server implementation:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define LISTENQ 5
int main()
{
struct sockaddr_in cli_addr, serv_addr;
char buffer[1024];
int serv_socket, cli_socket, clilen, io_buffer;
int tcp_port;
printf("Hello and welcome to the Server mode\n");
// ASKING FOR PORT NUMBER
if((serv_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0){
perror("server: can't open stream socket");
exit(EXIT_FAILURE);
}
printf("Please, enter the Server's Port (eg. 1320) \n");
scanf("%d", &tcp_port);
// CONFIGURING THE CONNECTION
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(tcp_port);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// ASSIGNING A NAME TO THE SOCKET
if(bind(serv_socket,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0){
perror("server: can't assign a name to the socket");
exit(EXIT_FAILURE);
}
printf("Server socket successfully configured\n");
printf("Server listening [Clients allowed: %d]\n", LISTENQ);
if(listen(serv_socket, LISTENQ) < 0)
{
perror("server: fail to listen network");
exit(EXIT_FAILURE);
}
// READ & WRITE STREAM
while(1){
//returns a file descriptor for the client
cli_socket = accept(serv_socket,(struct sockaddr *) &cli_addr,(socklen_t *) sizeof(cli_addr));
if(cli_socket < 0){
perror("server: accept error");
exit(EXIT_FAILURE);
}
printf("Server successfully connected to Client\n");
while(1)
{
if ((io_buffer=recv(cli_socket,buffer,sizeof(buffer),0))<0){
perror("ERROR: recv");
exit(EXIT_FAILURE);
}
printf("\"%s\" received from client", buffer);
if(strcmp(buffer, "FINISH") == 0)
{
break;
}
if ((io_buffer=send(cli_socket,buffer,strlen(buffer),0))!=strlen(buffer)){
perror("ERROR: send");
exit(EXIT_FAILURE);
}
bzero(buffer, sizeof(buffer));
}
strcpy(buffer, "OK");
if ((io_buffer=send(cli_socket, buffer, strlen(buffer), 0)) != strlen(buffer)){
perror("ERROR: send");
exit(EXIT_FAILURE);
}
printf("\"OK\" message sent to the Client.\n");
printf("Closing the connection \n");
for(int i=0; i < 5; i++)
{
printf(". ");
usleep(500000);
}
close(cli_socket);
}
}
In your original question, your accept call looks like this:
cli_socket = accept(serv_socket,(struct sockaddr *) &cli_addr,
(socklen_t *) sizeof(cli_addr));
This passes "(socklen_t *) sizeof(cli_addr)" as the third parameter to accept. This is expected to be a pointer to the size of the structure. You should be passing in a pointer to a socklen_t containing the size of the structure passed as parameter two. The size you're currently passing in is being interpreted as an address, which is then causing your program to crash when it is referenced. The code should look like this:
socklen_t cli_addr_size = sizeof(cli_addr);
cli_socket = accept(serv_socket,(struct sockaddr *) &cli_addr,
&cli_addr_size);
I am sending hello.c file from the client to the server. The server receives it and stores it as hello123.c. I am trying to compile this file and run it using the system() command.
In this hello.c / hello123.c, I am trying to connect back to the same client.
/* Server Program*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <signal.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h>
#define PORT 20001
#define BACKLOG 5
#define LENGTH 512
int main ()
{
int sockfd;
int nsockfd;
int num;
int sin_size;
struct sockaddr_in addr_local; /* client addr */
struct sockaddr_in addr_remote; /* server addr */
char revbuf[LENGTH];
/* Get the Socket file descriptor */
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
{
fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Obtaining socket descriptor successfully.\n");
/* Fill the client socket address struct */
addr_local.sin_family = AF_INET; // Protocol Family
addr_local.sin_port = htons(PORT); // Port number
addr_local.sin_addr.s_addr = INADDR_ANY; // AutoFill local address
bzero(&(addr_local.sin_zero), 8); // Flush the rest of struct
/* Bind a special Port */
if( bind(sockfd, (struct sockaddr*)&addr_local, sizeof(struct sockaddr)) == -1 )
{
fprintf(stderr, "ERROR: Failed to bind Port. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Binded tcp port %d in addr 127.0.0.1 sucessfully.\n",PORT);
/* Listen remote connect/calling */
if(listen(sockfd,BACKLOG) == -1)
{
fprintf(stderr, "ERROR: Failed to listen Port. (errno = %d)\n", errno);
exit(1);
}
else
printf ("[Server] Listening the port %d successfully.\n", PORT);
int success = 0;
while(success == 0)
{
sin_size = sizeof(struct sockaddr_in);
/* Wait a connection, and obtain a new socket file despriptor for single connection */
if ((nsockfd = accept(sockfd, (struct sockaddr *)&addr_remote, &sin_size)) == -1)
{
fprintf(stderr, "ERROR: Obtaining new Socket Despcritor. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Server has got connected from %s.\n", inet_ntoa(addr_remote.sin_addr));
char buffer[256];
bzero(buffer,256);
int n = 0;
n = read(nsockfd, buffer, 255);
if (n < 0) error("ERROR reading from socket");
printf("msg: %s\n",buffer);
/*Receive File from Client */
char* fr_name = "hello123.c";
FILE *fr = fopen(fr_name, "a");
if(fr == NULL)
printf("File %s Cannot be opened file on server.\n", fr_name);
else
{
bzero(revbuf, LENGTH);
int fr_block_sz = 0;
while((fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) > 0)
{
int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
if(write_sz < fr_block_sz)
{
error("File write failed on server.\n");
}
bzero(revbuf, LENGTH);
if (fr_block_sz == 0 || fr_block_sz != 512)
{
break;
}
}
if(fr_block_sz < 0)
{
if (errno == EAGAIN)
{
printf("recv() timed out.\n");
}
else
{
fprintf(stderr, "recv() failed due to errno = %d\n", errno);
exit(1);
}
}
printf("Ok received from client!\n");
fclose(fr);
}
system("gcc hello123.c -o hello123.out");
system("./hello123.out");
}
}
The following is the Client Program.
/* Client Program */
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <signal.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h>
#define PORT1 20001
#define PORT2 20002
#define LENGTH 512
int main(int argc, char *argv[]){
int sockfd;
int nsockfd;
char revbuf[LENGTH];
struct sockaddr_in remote_addr;
struct sockaddr_in server;
struct sockaddr_in dest;
int status,socket_fd, client_fd,num;
socklen_t size;
char buffer[1024];
char *buff, ch;
/* Get the Socket file descriptor */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor! (errno = %d)\n",errno);
exit(1);
}
/* Fill the socket address struct */
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(PORT1);
inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr);
bzero(&(remote_addr.sin_zero), 8);
/* Try to connect the remote */
if (connect(sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1)
{
fprintf(stderr, "ERROR: Failed to connect to the host! (errno = %d)\n",errno);
exit(1);
}
else
printf("[Client] Connected to server at port %d...ok!\n", PORT1);
/* Send File to Server */
//if(!fork())
//{
char* fs_name = "hello.c";
char sdbuf[LENGTH];
// char buffer[256];
int n;
fgets(buffer,255,stdin);
// bzero(buffer,256);
n = write(sockfd,buffer, strlen(buffer));
if(n<0) printf("Error: sending filename");
printf("[Client] Sending %s to the Server... ", fs_name);
FILE *fs = fopen(fs_name, "r");
if(fs == NULL)
{
printf("ERROR: File %s not found.\n", fs_name);
exit(1);
}
bzero(sdbuf, LENGTH);
int fs_block_sz;
while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs)) > 0)
{
if(send(sockfd, sdbuf, fs_block_sz, 0) < 0)
{
fprintf(stderr, "ERROR: Failed to send file %s. (errno = %d)\n", fs_name, errno);
break;
}
bzero(sdbuf, LENGTH);
}
printf("Ok File %s from Client was Sent!\n", fs_name);
//}
//while(1) {
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(PORT2);
inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr);
bzero(&(remote_addr.sin_zero), 8);
size = sizeof(struct sockaddr_in);
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1 )
{
perror("accept");
exit(1);
}
printf("Server got connection from client %s\n", inet_ntoa(dest.sin_addr));
while(1) {
if ((num = recv(client_fd, buffer, 1024,0))== -1) {
perror("recv");
exit(1);
}
else if (num == 0) {
printf("Connection closed\n");
//So I can now wait for another client
break;
}
buffer[num] = '\0';
printf("Server:Msg Received %s\n", buffer);
}//End of Inner While...
//Close Connection Socket
close(client_fd);
close (sockfd);
printf("[Client] Connection lost.\n");
return (0);
}
The following is the Hello.c
/* Hello.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 20002
#define MAXSIZE 1024
#define SA struct sockaddr
int main(int argc, char *argv[])
{
int sockfd,connfd;
struct sockaddr_in server_info;
struct hostent *he;
int socket_fd,client_fd,num;
char buffer[1024];
char i;
char buff[1024];
struct sockaddr_in servaddr,cli;
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd==-1)
{
printf("Hello:socket creation failed...\n");
exit(0);
}
else
printf("Hello:Socket successfully created..\n");
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
servaddr.sin_port=htons(PORT);
if(connect(sockfd,(SA *)&servaddr,sizeof(servaddr))!=0)
{
printf("Hello:connection with the server failed...\n");
exit(0);
}
else
printf("Hello:connected to the server..\n");
printf("\n Hello:Choose between 1 and 2\n");
printf("Hello:Enter Data for Server:\n");
fgets(buffer,MAXSIZE,stdin);
if ((send(socket_fd,buffer, strlen(buffer),0))== -1) {
fprintf(stderr, "Hello:Failure Sending Message\n");
close(socket_fd);
exit(1);
}
else {
printf("Hello:Client:Message being sent: %c\n",i);
close(socket_fd);
}
}
When I run the program, the file transfer is happening successfully. But the Hello.c is not getting connected to the client.
This is my output
Server Side:
$ ./server24.out
[Server] Obtaining socket descriptor successfully.
[Server] Binded tcp port 20001 in addr 127.0.0.1 sucessfully.
[Server] Listening the port 20001 successfully.
[Server] Server has got connected from 127.0.0.1.
msg:
Ok received from client!
Hello:Socket successfully created..
Hello:connection with the server failed...
Client Side:
$ ./client24.out
[Client] Connected to server at port 20001...ok!
[Client] Sending hello.c to the Server. Ok File hello.c from Client was Sent
accept: Socket operation on non-socket
I guess this is some address problem. But I am not able to figure out.
Please help.
Thanks in advance.
So your Client Program begin to act as a server but you haven't created the necessary socket to accept a connection there. socket_fd have been used uninitialized from socket()
Following need to be added updated after //while(1) { in Client
//while(1) {
/* Get the Socket file descriptor */
if ((socket_fd= socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor! (errno = %d)\n",errno);
exit(1);
}
/* Fill the socket address struct */
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(PORT2);
inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr);
bzero(&(remote_addr.sin_zero), 8);
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1 )
{
perror("accept");
exit(1);
}
I want to send one text file from client side and want to read the text file on the server side and want to display the texts on the server terminal screen. I have successfully written code for both server and multiple client. I have also sent a text file from client to server side. But now I want to know how to modify the text file and send it and read the text file on server end which is sent from the client side. My server and client code is given below together:
Server and Client Code:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
#define filename "//home//myname//Documents//folder1//folder2//input.txt"
#define MAX_CLIENTS 5
//the thread function
void *new_connection_handler(void *);
int main(int argc , char *argv[])
{
//client variables
int sock;
struct sockaddr_in server;
char buffer[256], server_reply[2000];
int len;
//server variables
int socket_desc , client_sock;
struct sockaddr_in client;
socklen_t c = sizeof(client);
//check if the the command contain less than two arguments
if(argc != 2)
{
printf("use either: %s <server/client>\n", argv[0]);
}
// If the command contains minumum 2 arguments
else{
// If argv is client then execute the client code
if(strcmp("client",argv[1]) == 0)
{
/****************/// Client code here **********************************************************************
//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
/* Time to send the file */
/******************************************************/
FILE *pf;
int fsize;
pf = fopen(filename, "rb");
if (pf == NULL)
{
printf("File not found!\n");
return 1;
}
else
{
printf("Found file %s\n", filename);
fseek(pf, 0, SEEK_END);
fsize = ftell(pf);
rewind(pf);
printf("File contains %ld bytes!\n", fsize);
printf("Sending the file now\n");
}
while (1)
{
// Read data into buffer. We may not have enough to fill up buffer, so we
// store how many bytes were actually read in bytes_read.
int bytes_read = fread(buffer, sizeof(buffer), 1, pf);
if (bytes_read == 0) // We're done reading from the file
break;
if (bytes_read < 0)
{
error("ERROR reading from file\n");
}
while (bytes_read > 0)
{
int bytes_written = write(sock, buffer, bytes_read);
if (bytes_written <= 0)
{
error("ERROR writing to socket\n");
}
}
}
printf("Done Sending the File!\n");
printf("Now Closing Connection.\n");
/*********************************************************************************/
close(sock);
}
/****************/// Server code here **********************************************************************
// If argv is server then execute the server code
if(strcmp("server", argv[1]) == 0 )
{
//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\n");
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];
//PROBLEM **read the text file sent from client side and display the text on screen**
while( (read_size = recv(sock , client_message , sizeof(client_message) , 0)) > 0 )
printf("Read Text: %.*s", read_size, client_message);
if(read_size == 0)
{
printf("Client disconnected\n");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
return 0;
}
You had done some mistakes in your code.
int bytes_read = fread(buffer, sizeof(buffer), 1 ,pf);
This statement is wrong, when you print the bytes_read value it print 1 has a result.If you pass this to next while it will print the h repeatedly.
Use this below statement instead of that fread:
int bytes_read = fread(buffer, 1, sizeof(buffer), pf);
This statement only returns the correct readed value.
while (bytes_read > 0)
{
int bytes_written = write(sock, buffer, bytes_read);
if (bytes_written <= 0)
{
error("ERROR writing to socket\n");
}
}
In this part of the code your program writing the readed content again and again into the socket without break, so the server is print the text without break.
So use this statement after the write() bytes_read=bytes_read-bytes_written; if the read buffer is fully written in your socket it break the statement.
And one more thing is always try to use long data type, when you are trying to use file, because int has lower range compared to long.
UPDATE:
Put the fread(buffer, 1, sizeof(buffer), pf); and try it. It will work.
You can use open() or fopen().
fd=open("filename",O_RDWR);
fd - returns descriptor of the opened file.
O_RDWR - which is used to open file for read and write, you must include fcntl.h.
fp=fopen("filename","r+");
fp - File pointer.
rw - Opened file for both read and write.
File content:
Chandru
ttttt.
After replace:
Stackoverflowt.
Here the content is big so the content is overwritten in the another line.
To avoid that you need to write the changed content in another file.
Writing in another file would be easy to append the text in the line end.
I've added a Unix domain socket to a project I'm working on. The socket has a simple function, it simply broadcasts data that the code extracts from another device, the idea is that other applications will be able to read this data from the socket.
I've written a simple server code, and when I run the code on my laptop, using a Ubuntu 10.04 VM, it works perfectly well. However, when I copy the code over onto the embedded device I'm using the code fails, when my application tries to write to the socket the code exits.
In /var/log/messages I see the following messages:
Dec 2 15:12:17 box local1.info my-app[17338]: Socket Opened
Dec 2 15:12:17 box local1.err my-app[17338]: Socket Failed
Dec 2 15:12:17 box local1.err my-app[17338]: Protocol wrong type for socket
Dec 2 15:12:38 box local1.info ./server[17178]: accept failed: Invalid argument
Here is the server code:
#include <stdio.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include<syslog.h>
#define SV_SOCK_PATH "/tmp/rtig.sock" //path to be used by socket
#define BUF_SIZE 256 //Max length of string listened to
#define BACKLOG 5
int main(int argc, char *argv[]){
struct sockaddr_un addr;
int sfd, cfd; //File Descriptors for the server and the client
ssize_t numRead; //Length of the string read from the client.
u_int8_t buf[BUF_SIZE]; //String that reads messages
char plain[BUF_SIZE]; //Plain string for writing to the log
memset(plain, 0, sizeof plain); //blank out plain string
openlog(argv[0], LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); //Write the messages to the syslog
//---Declare socket--------------------------------------
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if(sfd!=0){
syslog(LOG_INFO, "socket success");
}
else{
syslog(LOG_INFO, "socket unsuccessful");
}
//--Test to see if there's already a socket at SV_SOCK_PATH, and remove it if there is.
if (remove(SV_SOCK_PATH) == -1 && errno !=ENOENT){
syslog(LOG_INFO, "error removing socket");
}
//-----------------------------------------------------------
//--blank out the socket address, then write the information to it
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SV_SOCK_PATH, sizeof(addr.sun_path)-1); //ensure path is null terminated
//----Bind the socket to the address-------------------------------------
if (bind(sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un))!=0){
syslog(LOG_INFO, "bind unsuccessful");
}
else{
syslog(LOG_INFO, "bind successful");
}
//------------------------------------------------------------------------
//-----Listen on the socket-----------------------------------------------
if (listen(sfd, BACKLOG) != 0){
syslog(LOG_INFO, "listen failed");
}
else{
syslog(LOG_INFO, "listen succeeded");
}
//-------------------------------------------------------------------------
//--------Accept messages on the socket------------------------------------
socklen_t csize;
while(1){
cfd = accept(sfd, (struct sockaddr *)&addr,&csize);
if (cfd < 0) {
syslog(LOG_INFO, "accept failed: %s", strerror(errno));
}
while ( (numRead=read(cfd, buf, BUF_SIZE)) > 0 ){
dump_packet(buf, numRead);
}
}
//-------------------------------------------------------------------------
//---code never gets here but this is how to close the log and the socket--
closelog();
close(cfd);
}
And here's a simple version of the client that connects to this server from my app:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SV_SOCK_PATH "/tmp/rtig.sock" //path to be used by socket
#define BACKLOG 5
int isDaemon = 1;
void etmlog(int level, char *message)
{
isDaemon == 1 ? syslog(level, message) : printf(message);
}
int main(){
struct sockaddr_un addr;
unsigned int sockfd;
ssize_t numRead;
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) > 0) {
etmlog(LOG_INFO, "Socket Opened\n");
}
else {
etmlog(LOG_ERR, "Socket Failed:\n");
etmlog(LOG_ERR, strerror(errno));
exit(-1);
}
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SV_SOCK_PATH, sizeof(addr.sun_path) - 1); // -1 ensures null terminated string
if (connect
(sockfd, (struct sockaddr *)&addr,
sizeof(struct sockaddr_un)) == -1) {
etmlog(LOG_ERR, "Socket Failed\n");
etmlog(LOG_ERR, strerror(errno));
exit(1);
} else {
etmlog(LOG_INFO, "Socket Connection Successful\n");
}
while (1){
// some data is read into buf up here
if (write(sockfd, buf, rdlen) < 0) {
etmlog(LOG_ERR, "Write to Socket Failed:");
etmlog(LOG_ERR, strerror(errno));
}
}
close(sockfd);
return 0;
}
I appreciate that I've just posted a lot of code to read through, but I'd be very grateful if someone could give me a few pointers on this.
You are not using accept correctly. The third argument must be initialized to the size of the second argument, so that accept won't overflow it. See man accept.
I am trying to implement a server-client application in which the client sends the name of file to server. The server looks for the file and if the file exist it sends the file to the client back and this goes on . Here is the code i have written but the problem is that the server does not send the content of file back to client I had the same problem earlier ,then i re-wrote the code .
Here is the code :-
Server Side
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
int main() {
char buff[20];
char content[200];
int sd, connfd, len, bytes_read;
struct sockaddr_in servaddr, cliaddr;
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd == -1) {
puts("socket not created in server");
return 1;
} else {
puts("socket created in server");
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(7802);
if (bind(sd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
puts("Not binded");
return 1;
} else {
puts("Binded");
}
len = sizeof(cliaddr);
recvfrom(sd, buff, 1024, 0, (struct sockaddr *)&cliaddr, &len);
printf("%s\n", buff);
FILE *fp = fopen(buff, "r");
if (fp == NULL) {
printf("File does not exist \n");
return 1;
}
while (1) {
bytes_read = read(fp, content, sizeof(content));
if (bytes_read == 0)
break;
sendto(sd, content, sizeof(content), 0, (struct sockaddr*)&cliaddr, len);
bzero(content, 200);
}
strcpy(content, "end");
sendto(sd, content, sizeof(content), 0, (struct sockaddr*)&cliaddr, len);
return 0;
}
Client side:
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netinet/in.h>
#include <sys/types.h>
int main() {
int count = 0;
char buff[20], output[20];
char file_buffer[200];
int sockfd, connfd, len;
struct sockaddr_in servaddr, cliaddr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
puts("socket not created in client");
return 1;
} else {
puts("socket created in client");
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY; // ANY address or use specific address
servaddr.sin_port = htons(7802); // Port address
puts("Type your UDP client message");
scanf("%s", buff);
puts("enter the name of new file to be saved");
scanf("%s", output);
// send msg to server
sendto(sockfd, buff, strlen(buff) + 1, 0,
(struct sockaddr *)&servaddr, sizeof(struct sockaddr));
count++;
printf("%d\n", count);
FILE *fp = fopen(output, "a");
if (fp == NULL) {
puts("error in file handling");
return 1;
}
recvfrom(sockfd, file_buffer, sizeof(file_buffer), 0, NULL, NULL);
while (1) {
if (strcmp(file_buffer, "end") == 0)
break;
printf("%s", file_buffer);
write(fp, file_buffer, strlen(file_buffer));
bzero(file_buffer, 200);
recvfrom(sockfd, file_buffer, sizeof(file_buffer), 0, NULL, NULL);
}
puts("completed");
return 0;
}
Probably you should use the fread() function instead of read() on server side.
Functions fopen() and read() are parts of different interfaces:
Family read() -> open, close, read, write, ioctl (system calls)
Family fread() -> fopen, fclose, fread, fwrite, fcntl (standard library)
I can suppose that file descriptor given by fopen() is not exactly the same as read() expects.
The same on client side. You use the fopen() to open file and write() to write. Please use the fwrite()