Writing the C source below using Unix local sockets I got an error about the address already in use. After having checked man 7 Unix for further informations I tried to create a sub-folder where executing my program (obviously modifying the sun_path field on the current folder) but the error was ever the same.
Is there someone able to help me?
Source code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>
#define MAXLEN 128
int main (int argc, char *argv[]){
struct sockaddr_un server;
int serverfd, clientfd;
socklen_t addrsize = sizeof(struct sockaddr_un);
char buff[MAXLEN], *path;
if (argc < 2){
printf("Error: %s [MESSAGE]\n", argv[0]);
return 1;
}
if ((serverfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
printf("Error \"%s\" in socket()\n", strerror(errno));
exit(1);
}
puts("socket()");
server.sun_family = AF_UNIX;
path = strcpy(server.sun_path, "/home/myhome/Dropbox/Sources/C/sub");
printf("[DEBUG]Address bound at %s\n", path);
if ((bind(serverfd, (struct sockaddr*)&server, addrsize)) < 0){
printf("Error \"%s\" in bind()\n", strerror(errno));
exit(1);
}
puts("bind()");
if ((listen(serverfd, 1)) < 0){
printf("Error \"%s\" in listen()\n", strerror(errno));
exit(1);
}
if ((clientfd = accept(serverfd, NULL, &addrsize)) < 0){
printf("Error \"%s\" in accept()\n", strerror(errno));
exit(1);
}
write(clientfd, argv[1], strlen(argv[1]));
read(clientfd, buff, sizeof(buff));
puts(buff);
close(clientfd);
close(serverfd);
return 0;
}
You should unlink() the path file before bind call. You will get this error when file exists during the bind. Either you should ensure to unlink/remove the file before exiting the application or you could always unlink it before bind.
Check man page of bind. Also, note the example given in the man page at the end.
You can try to use the SO_REUSEADDR flag like so:
int yes = 1;
if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
// error handling
exit(1);
}
Related
I am trying to execute cat|grep using a client server set-up, works as follows: client sends word to search for using grep, server executes cat|grep, sends results to client but the recv() function seems to be messing up with my code.
What's the problem?
Adding the recv() function makes other parts of my code not working, every puts() works until puts("test5"); which is where my code is stuck in the execution, putting the recv() function as a comment makes the code run fine.
Till now I am not using the word I send from the client in any way so the problem must be with the receive function itself, it's not giving an error and when I print the content I send it works fine.
Here is the relevant client part:
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include<errno.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
int buffer[1024];
char buffer2[1024]={0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
perror("Invalid address \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("Connection Failed \n");
return -1;
}
int i, array[argc], countsize=0;
if(argc>=2)
{
for(i=1; i<argc; i++)
{
int number=atoi(argv[i]);
array[i-1]=number;
countsize++;
}
if(send(sock, array, countsize*sizeof(int), 0)<0)
{
printf("Error in send! %s\n", strerror(errno));
return -1;
}
if(argc>=2)
{
int i=0;
for(int i=0; i<argc; i++)
{
if(atoi(argv[i])==6)
{
puts("Please enter the name/word you want to search for in the history file: ");
char word[30];
fgets(word, 30, stdin);
if(send(sock, &word , 30, 0)<0)
printf("Error in send! %s\n", strerror(errno));
valread = read( sock , buffer2, 1024);
puts("The result cat|grep is:");
printf("%s\n", buffer2);
}
}
}
}
return 0;
}
Here is the server's main method:
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include<errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <sys/wait.h>
#include<time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
#include <arpa/inet.h>
#define PORT 8080
void *catgrep(void *);
int main()
{
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer2[1024]={0};
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR , &opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
while (1)
{
if (listen(server_fd, 20) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
int arguments[10]={0};
int n = recv(new_socket, arguments ,1024*sizeof(int),0);
int j;
int argumentsize=n/sizeof(int);
for(j=0; j<argumentsize;j++)
{
if(arguments[j]==6)
{
pthread_t th5;
pthread_attr_t attr5;
pthread_attr_init(&attr5);
if(pthread_create(&th5,&attr5, catgrep,&new_socket)!=0)
{
printf("Error in pthread_create %s\n", strerror(errno));
return -1;
}
pthread_join(th5, NULL);
return -1;
}
}
close(new_socket);
}
close(server_fd);
return 1;
}
Here is my catgrep() method:
void *catgrep(void * param)
{
int *sock = (int*) param;
int new_sock = *sock;
int fd[2];
pipe(fd);
pid_t pid = fork();
char word[30];
recv(new_sock, word ,30, 0); //when I put this line code
starts messing up.
puts(word);
if(pid==0)
{
close(1);
dup(fd[1]);
close(fd[0]);
close(fd[1]);
char *cat_args[] = {"/bin/cat", "GameData.txt", NULL};
if(execv(cat_args[0], cat_args)<0)
{
printf("Error in execv! %s\n", strerror(errno));
}
exit(0);
}
if(pid > 0)
{
close(0);
dup(fd[0]);
close (fd[1]);
close(fd[0]);
puts("test2");
FILE *fp2;
if ((fp2 = popen("grep -w tries", "r")) == NULL)
{
perror("popen failed");
return NULL;
}
puts("test3");
size_t str_size = 1024;
char *stringts2 = malloc(str_size);
if (!stringts2)
{
perror("stringts allocation failed");
return NULL;
}
puts("test4");
stringts2[0] = '\0';
char buf[128];
size_t n;
puts("test5"); //when I use the recv() program gets stuck here.
while ((n = fread(buf, 1, sizeof(buf) - 1, fp2)) > 0)
{
puts("test10");
buf[n] = '\0';
size_t capacity = str_size - strlen(stringts2) - 1;
while (n > capacity)
{
str_size *= 2;
stringts2 = realloc(stringts2, str_size);
if (!stringts2)
{
perror("stringts realloation failed");
return NULL;
}
capacity = str_size - strlen(stringts2) - 1;
}
strcat(stringts2, buf);
}
puts("test6");
if (pclose(fp2) != 0)
{
perror("pclose failed");
return NULL;
}
puts("test7");
if(send(new_sock, stringts2, 10000, 0)<0)
{
printf("Error in send! %s\n", strerror(errno));
}
}
return NULL;
}
Few notes:
I am aware that in this particular piece of code I am not using the word sent by the client, hence why some lines are as comments, I will implement this when my problem gets fixed.
I am using popen() as I want to return the output of catgrep().
I isolated the problem and not it's only happening when I include the recv() function.
The word I am sending is being printed when I use recv() so the function isn't causing errors but it's messing up other parts.
UPDATE:
As suggested by someone in the comments I changed the way I receive the word sent by my client, I am now using the following:
int count = 0;
int total = 0;
while ((count = recv(new_sock, &word[total], sizeof word - count, 0)) > 0)
{
total=total+count;
}
if (count==-1)
{
perror("error in recv()");
}
Still having the same problem and same output.
The basic problem is that you are confusing strings and byte streams -- they're not the same thing.
In your client, you send some data with:
char word[30];
fgets(word, 30, stdin);
if(send(sock, &word , 30, 0)<0)
This will read a line (including a newline) into the beginning of an on-stack buffer, and then send the entire buffer, including whatever garbage happens to be in it after the end of the string. You probably don't want the newline, maybe don't want the NUL terminator, and certainly don't want the garbage.
In addition, you don't check the return value of send for a short send -- in some (admittedly rare) situations, a send might not send all the data you request.
On the reading side you don't check the return value of recv to see how many bytes you got, which may be different from what you expect -- there's no guarentee that there will be 1:1 correspondence between send and recv calls on a connection. One send might get broken up and split across multiple recvs, and several sends might have their data combined and returned in one recv. So you always need to check the return value of recv to see how many bytes you actually got.
Trying to run C executable gives me
Error opening file --> No such file or directory
when the file is clearly there. Does anyone know the cause of this issue? I'm simply compiling a C program using gcc and trying to run the executable. See the following
This is on a
root#EmRtkGps3[~/socket]# ls
serverFile.c sf
root#EmRtkGps3[~/socket]# ./sf
Error opening file --> No such file or directoryroot#EmRtkGps3[~/socket]#
The version of linux I'm running:
Linux EmRtkGps3 3.10.98-poky-edison+ #1 SMP PREEMPT Wed Jul 12 18:30:01 MSK 2017 i686 GNU/Linux
serverFile.c
/* Server code */
/* TODO : Modify to meet your need
from
https://stackoverflow.com/questions/11952898/c-send-and-receive-file
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#define PORT_NUMBER 5000
#define SERVER_ADDRESS "192.168.0.103"
#define FILE_TO_SEND "/home/root/logs/*.UBX"
int main(int argc, char **argv)
{
int server_socket;
int peer_socket;
socklen_t sock_len;
ssize_t len;
struct sockaddr_in server_addr;
struct sockaddr_in peer_addr;
int fd;
int sent_bytes = 0;
char file_size[256];
struct stat file_stat;
off_t offset;
int remain_data;
/* Create server socket */
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1)
{
fprintf(stderr, "Error creating socket --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Zeroing server_addr struct */
memset(&server_addr, 0, sizeof(server_addr));
/* Construct server_addr struct */
server_addr.sin_family = AF_INET;
inet_pton(AF_INET, SERVER_ADDRESS, &(server_addr.sin_addr));
server_addr.sin_port = htons(PORT_NUMBER);
/* Bind */
if ((bind(server_socket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))) == -1)
{
fprintf(stderr, "Error on bind --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Listening to incoming connections */
if ((listen(server_socket, 5)) == -1)
{
fprintf(stderr, "Error on listen --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fd = open(FILE_TO_SEND, O_RDONLY);
if (fd == -1)
{
fprintf(stderr, "Error opening file --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Get file stats */
if (fstat(fd, &file_stat) < 0)
{
fprintf(stderr, "Error fstat --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "File Size: \n%d bytes\n", file_stat.st_size);
sock_len = sizeof(struct sockaddr_in);
/* Accepting incoming peers */
peer_socket = accept(server_socket, (struct sockaddr *)&peer_addr, &sock_len);
if (peer_socket == -1)
{
fprintf(stderr, "Error on accept --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "Accept peer --> %s\n", inet_ntoa(peer_addr.sin_addr));
sprintf(file_size, "%d", file_stat.st_size);
/* Sending file size */
len = send(peer_socket, file_size, sizeof(file_size), 0);
if (len < 0)
{
fprintf(stderr, "Error on sending greetings --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "Server sent %d bytes for the size\n", len);
offset = 0;
remain_data = file_stat.st_size;
/* Sending file data */
while (((sent_bytes = sendfile(peer_socket, fd, &offset, BUFSIZ)) > 0) && (remain_data > 0))
{
fprintf(stdout, "1. Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n", sent_bytes, offset, remain_data);
remain_data -= sent_bytes;
fprintf(stdout, "2. Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n", sent_bytes, offset, remain_data);
}
close(peer_socket);
close(server_socket);
return 0;
}
So I am trying to work on this toy client file server problem.
The iterative version works fine, but when I attempt to fork each new connection in the server code, the client code hangs on the recv call.
I am fairly sure the issue is with the peer_socket, but I have been unable to find my mistake.
It completes just fine if I hit the server with a Ctrl-c though.
CLIENT CODE:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#define PORT_NUMBER 5108
#define SERVER_ADDRESS "localhost"
//#define FILENAME "test.txt"
int main(int argc, char **argv)
{
int client_socket;
ssize_t len;
struct sockaddr_in remote_addr;
char buffer[BUFSIZ];
char filename[256];
char local_filename[256];
int file_size;
FILE *received_file;
int remain_data = 0;
/* Zeroing remote_addr struct */
memset(&remote_addr, 0, sizeof(remote_addr));
memset(local_filename, 0, sizeof(local_filename));
if(argc >1){
strncpy(local_filename, argv[1], 256);
}
/* Construct remote_addr struct */
remote_addr.sin_family = AF_INET;
inet_pton(AF_INET, SERVER_ADDRESS, &(remote_addr.sin_addr));
remote_addr.sin_port = htons(PORT_NUMBER);
/* Create client socket */
client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == -1)
{
fprintf(stderr, "Error creating socket --> %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
//Prompt for file to retrieve
printf("Enter file name: ");
fgets(filename,sizeof(filename),stdin);
printf("Getting file %s", filename);
/* Connect to the server */
if (connect(client_socket, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1)
{
fprintf(stderr, "Error on connect --> %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
//Send filename to server
/*if(!send(client_socket,filename, sizeof(filename))) {
printf("Error sending filename\n");
exit(EXIT_FAILURE);
}*/
send(client_socket,filename, sizeof(filename),0);
printf("success\n");
/* Receiving file size */
memset(&buffer, 0, sizeof(buffer));
recv(client_socket, buffer, sizeof(buffer), 0);
file_size = atoi(buffer);
fprintf(stdout, "\nFile size : %d\n", file_size);
if(!local_filename[0]) {
received_file = fopen("test2.txt", "w");
}else{
received_file = fopen(local_filename, "w");
}
if (received_file == NULL)
{
fprintf(stderr, "Failed to open file foo --> %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
remain_data = file_size;
//THIS IS THE LOOP THAT HANGS!
while (((len = recv(client_socket, buffer, BUFSIZ, 0)) > 0) && (remain_data > 0))
{
fwrite(buffer, sizeof(char), len, received_file);
remain_data -= len;
fprintf(stdout, "Receive %d bytes and we hope :- %d bytes\n", len, remain_data);
}
printf("did we reach here in the code?\n");
fclose(received_file);
printf("did we reach here in the code?\n");
close(client_socket);
return 0;
}
SERVER CODE:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <signal.h>
#define PORT_NUMBER 5108
#define SERVER_ADDRESS "localhost"
//#define FILE_TO_SEND "hello.c"
int main(int argc, char **argv)
{
int server_socket;
socklen_t global_sock_len;
struct sockaddr_in server_addr;
struct sockaddr_in peer_addr;
/* Create server socket */
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1)
{
fprintf(stderr, "Error creating socket --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Zeroing server_addr struct */
memset(&server_addr, 0, sizeof(server_addr));
/* Construct server_addr struct */
server_addr.sin_family = AF_INET;
inet_pton(AF_INET, SERVER_ADDRESS, &(server_addr.sin_addr));
server_addr.sin_port = htons(PORT_NUMBER);
/* Bind */
if ((bind(server_socket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))) == -1)
{
fprintf(stderr, "Error on bind --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Listening to incoming connections */
if ((listen(server_socket, 5)) == -1)
{
fprintf(stderr, "Error on listen --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
//attempt multiple connections via fork
int peer_socket;
int fid;
while(1) {
bool servexit = false;
printf("did we reach HERE in the code?%d\n",getpid());
peer_socket = accept(server_socket, (struct sockaddr *) &peer_addr, &global_sock_len);
//printf("did we reach HERE in the code?\n");
if (peer_socket == -1) {
fprintf(stderr, "Error on accept --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
if((fid = fork()) == -1) {
printf("error\n");
close(peer_socket);
//continue;
}else if(fid > 0){
printf("parent\n");
close(peer_socket);
//continue;
}else if(fid == 0) {
printf("child\n");
socklen_t sock_len;
ssize_t len;
int fd;
int sent_bytes = 0;
char FILE_TO_SEND[256];
char file_size[256];
struct stat file_stat;
off_t offset;
int remain_data;
//int peer_socket = peer_socket;
recv(peer_socket, FILE_TO_SEND, sizeof(FILE_TO_SEND), 0);
printf("Client requested %s", FILE_TO_SEND);
if (strlen(FILE_TO_SEND) > 1) {
strtok(FILE_TO_SEND, "\n");
}
//check for server close command from client
if(strcmp(FILE_TO_SEND,"quit") == 0){
servexit = true;
printf("Quiting server\n");
close(server_socket);
close(peer_socket);
pid_t pid = getppid();
kill(pid, SIGKILL);
exit(0);
}else {
fd = open(FILE_TO_SEND, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "Error opening file --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Get file stats */
if (fstat(fd, &file_stat) < 0) {
fprintf(stderr, "Error fstat --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "File Size: \n%d bytes\n", file_stat.st_size);
sock_len = sizeof(struct sockaddr_in);
fprintf(stdout, "Accept peer --> %s\n", inet_ntoa(peer_addr.sin_addr));
sprintf(file_size, "%d", file_stat.st_size);
/* Sending file size */
len = send(peer_socket, file_size, sizeof(file_size), 0);
if (len < 0) {
fprintf(stderr, "Error on sending greetings --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "Server sent %d bytes for the size\n", len);
//fflush((FILE*)peer_socket);
offset = 0;
remain_data = file_stat.st_size;
/* Sending file data */
while (((sent_bytes = sendfile(peer_socket, fd, &offset, BUFSIZ)) > 0) && (remain_data > 0)) {
fprintf(stdout,
"1. Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n",
sent_bytes, offset, remain_data);
remain_data -= sent_bytes;
fprintf(stdout,
"2. Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n",
sent_bytes, offset, remain_data);
}
}
break;
}
}
return 0;
}
Ok, so, it turns out that sendfile() doesn't play as nicely as send() in this situation. I found two fixes.
1.) Use send() instead of sendfile()
2.) Retry in both sendfile() (Server) and recv() (client) if either returns -1 (error)
I am writing simple client-server program. Essentially I am following example from "Linux Network Programming" book. This is simple TCP server
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#define SERVERPORT 8888
#define MAXBUF 1024
int main(int argc, char* argv[])
{
int socket1, socket2;
int addrlen;
struct sockaddr_in fServer, fClient;
int status;
socket1=socket(AF_INET, SOCK_STREAM, 0);
if(socket1==-1)
{
printf("Could not create the socket\n");
exit(1);
}
fServer.sin_family=AF_INET;
fServer.sin_addr.s_addr=INADDR_ANY;
fServer.sin_port= htons(SERVERPORT);
status=bind(socket1, (struct sockaddr*) &fServer,
sizeof(fServer));
if(status==-1)
{
printf("could not bind the socket\n");
exit(1);
}
else printf("socket is created\n");
status=listen(socket1, 5);
if(status==-1)
{
printf("could not listen socket\n");
exit(1);
}
else printf("socket is waiting for connection\n");
for(;;)
{
int fd;
int i, readCounter, writeCounter;
char* bufptr;
char buf[MAXBUF];
char filename[MAXBUF];
addrlen=sizeof(fClient);
socket2=accept(socket1, (struct sockaddr*) &fClient, &addrlen);
if(socket2==-1)
{
printf("could not accept connection\n");
exit(1);
}
else printf("connection established, waiting for the file name\n");
i=0;
if((readCounter=read(socket2, filename, MAXBUF))>0)
i+=readCounter;
filename[i+1]='\0';
printf("reading from the file\n");
fd=open(filename, O_RDONLY);
if(fd==-1)
{
printf("could not open the file\n");
perror(" error is detected: ");
close(socket2);
continue;
}
else printf("file name is recieved, started copying\n");
readCounter=0;
while((readCounter=read(fd, buf, MAXBUF))>0)
{
writeCounter=0;
bufptr=buf;
while(writeCounter<readCounter)
{
readCounter-=writeCounter;
bufptr+=writeCounter;
writeCounter=write(socket2, bufptr, readCounter);
if(writeCounter==-1)
{
printf("could not write the file to client\n");
close(socket2);
continue;
}
}
}
close(fd);
close(socket2);
}
close(socket1);
return 0;
}
This code is for client.
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#define SERVERPORT 8888
#define MAXBUF 1024
int main(int argc, char* argv[])
{
int sockd;
int counter;
int fd;
struct sockaddr_in fServer;
char buf[MAXBUF];
int status;
if(argc<3)
{
printf("Incorrect data provided\n");
exit(1);
}
sockd=socket(AF_INET, SOCK_STREAM,0);
if(sockd==-1)
{
printf("could not create socket\n");
exit(1);
}
fServer.sin_family=AF_INET;
fServer.sin_addr.s_addr=inet_addr(argv[1]);
fServer.sin_port=htons(SERVERPORT);
status=connect(sockd, (struct sockaddr*)&fServer,
sizeof(fServer));
if(status==-1)
{
printf("could not connect to server\n");
exit(1);
}
status=write(sockd, argv[2], strlen(argv[2]+1));
if(status==-1)
{
printf("could not send file name to server\n");
exit(1);
}
shutdown(sockd, SHUT_WR);
fd=open(argv[2], O_WRONLY| O_CREAT| O_APPEND);
if(fd==-1)
{
printf("could not open destination file\n");
exit(1);
}
while((counter=read(sockd, buf, MAXBUF))>0)
{
write(fd, buf, counter);
}
if(counter==-1)
{
printf("file transfer is complete\n");
exit(1);
}
printf("file transfer is complete\n");
close(sockd);
return 0;
}
I pass file name from the same directory as server. I pass filename as agrc[2] parameter. Server oputput however is the following
socket is created
socket is waiting for connection
connection established, waiting for the file name
reading from the file
could not open the file
error is detected: : No such file or directory
connection established, waiting for the file name
reading from the file
could not open the file
error is detected: : No such file or directory
I entered the filename on my first attempt, then I enterd full path but still recieving the same message. So what is the problem? thanks in advance
Client:
status=write(sockd, argv[2], strlen(argv[2]+1));
strlen(argv[2]+1) should be strlen(argv[2])+1 if you want to include the \0.also: you do not close your fd. close(sockd); should be close(fd);
Server:
filename[i+1]='\0'; should be filename[i]='\0'; if you are not sure you received the \0.
if you are sending 1 char, for example 'a', i would be 1 and your array would look like
filename[0] = 'a'
filename[i] = undefined
filename[i+1] = '\0'
Unrelated to your problem, but on the server side you should advance bufptr after write(), not before.
Also: TCP is a stream protocol; there is no guarantee that a write() on one end of a connection will be completely read by a single recv() on the other end.
Good evening to all,
For kicks and giggles I'm trying my hand at *NIX sockets and TCP/IP. Now, to get off the ground I'm simply trying to create a socket on two endpoints and a basic text chat program back and forth. Now, before I'm even up and running I'm hit with a bind 'Invalid Argument':
user#user-VirtualBox:~/sockets$ ./socket
sock=3
s_->sin_family = 2
s_->sin_port = 3879
s_->sin_addr.s_addr = 0
sockfd = 3
s_->sin_family = 2
s_->sin_port = 3879
s_->sin_addr.s_addr = 0
Socket bind error: Invalid argument
sizeof(s_) = 8
Code below. so, INADDR_ANY should be 255.255.225.255 = 0, from what I understand; AF_INET is 2; and sin_port, well, I've looked at the binary backward and forward and am not sure I understand how 9000 is represented in host order at 3879 from 9000, but assume it's a non-issue. Additionally, since 1 is stdout and 2 is stderr, I assume that anything above this is dynamically allocated and so 3 should be fine for the socket file descriptor.
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
void setSocket(struct sockaddr_in* s_){
s_->sin_family=AF_INET;
s_->sin_port=htons(9999);
s_->sin_addr.s_addr=INADDR_ANY;
memset(&(s_->sin_zero), '\0', 8);
printf("s_->sin_family = %i\n", s_->sin_family);
printf("s_->sin_port = %i\n", s_->sin_port);
printf("s_->sin_addr.s_addr= %i\n", s_->sin_addr.s_addr);
}
void createSocket(int *sock){
if ((*sock = socket(AF_INET, SOCK_STREAM, 0)) == -1){
fprintf(stderr, "Socket creation error: %s\n", strerror(errno));
exit(1);
}
printf("sock = %i\n", *sock);
fflush(stdout);
}
void bindSocket(int sock, struct sockaddr_in* s_){
printf("s_->sin_family = %i\n",s_->sin_family);
printf("s_->sin_port = %i\n",s_->sin_port);
printf("s_->sin_addr.s_addr = %i\n",s_->sin_addr.s_addr);
if((bind(sock, (struct sockaddr*)s_, (socklen_t)sizeof(s_))) == -1){
fprintf(stderr, "Socket bind error: %s\n", strerror(errno));
}
printf("sizeof(s_) = %lu\n", sizeof(s_));
}
int main(int argc, char* argv[]){
int sockfd;
struct sockaddr_in socket_;
createSocket(&sockfd);
setSocket(&socket_);
printf("sockfd = %i\n", sockfd);
fflush(stdout);
bindSocket(sockfd, &socket_);
exit(0);
}
I believe the problem is the
sizeof()
inside your bind()... 's_' is a pointer, so its sizeof is (probably) 4...
You need to dereference it:
if((bind(sock, (struct sockaddr*)s_, (socklen_t)sizeof(*s_))) == -1){
fprintf(stderr, "Socket bind error: %s\n", strerror(errno));
}