I am receiving more bytes than I am sending on server side, and the file I receive has some garbage characters at the start of my file.
client code
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <dirent.h>
#include <time.h>
int main() {
int serverPort, clientPort, clientSock, serverSock;
scanf("%d", &clientPort);
struct sockaddr_in cadd, sadd1, sadd2, clen, slen;
cadd.sin_family = AF_INET;
cadd.sin_addr.s_addr = inet_addr("127.0.0.1");
cadd.sin_port = htons(clientPort);
clientSock = socket(AF_INET, SOCK_STREAM, 0);
if(clientSock == -1)
fprintf(stderr, "unable to create socket: %s\n", strerror(errno));
int result = connect(clientSock, (struct sockaddr *)&cadd, sizeof(cadd) );
if(result == -1) {
fprintf(stderr, "unable to create socket: %s\n", strerror(errno));
return -1;
}
while(1) {
struct stat stat_buf;
off_t offset = 0;;
int choice = 1;
int fd = open("myList.txt", O_RDONLY);
if (fd == -1) {
fprintf(stderr, "unable to open %s", strerror(errno));
exit(1);
}
fstat(fd, &stat_buf);
offset = 0;
int size = (int)stat_buf.st_size;
printf("File size: %d\n", size);
send(clientSock, &size, sizeof(stat_buf.st_size), 0);
int sent = sendfile(clientSock, fd, &offset, stat_buf.st_size);
if(sent == -1) {
fprintf(stderr, "error sendfile: %s\n", strerror(errno));
exit(1);
}
if(sent != stat_buf.st_size) {
fprintf(stderr, "error sendfile %d of %d bytes\n", sent, (int)stat_buf.st_size);
exit(1);
}
printf("sendfile succesfull %d\n", sent);
break;
}
}
server code
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <dirent.h>
#include <time.h>
int main() {
int serverPort, sock;
printf("Enter port number: ");
scanf("%d", &serverPort);
struct sockaddr_in server1, server2;
int addrlen = sizeof(server2);
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1) {
fprintf(stderr, "unable to create socket: %s\n", strerror(errno));
exit(1);
}
server1.sin_family = AF_INET;
server1.sin_port = htons(serverPort);
int rc = bind(sock, (struct sockaddr *) &server1, sizeof(server1));
if(rc == -1) {
fprintf(stderr, "bind error: %s\n", strerror(errno));
close(rc);
exit(1);
}
rc = listen(sock, 1);
if(rc == -1) {
fprintf(stderr, "listen failed: %s\n", strerror(errno));
exit(1);
}
while(1) {
int con = accept(sock, (struct sockaddr *) &server2, &addrlen);
int crt = creat("please.txt", S_IRWXU), size, count = 0;
recv(con, &size, sizeof(size), 0);
while(1) {
char mssg[100];
memset(mssg, '\0', sizeof(mssg));
int n = recv(con, mssg, sizeof(mssg), 0);
int wrt = write(crt, mssg, n);
count = count + wrt;
printf("Count: %d\n", count);
if(count >= size)
break;
}
printf("Write successful\n");
}
}
Attaching the screen-shots
client send =>
[server recv] =>
In the client you do this:
send(clientSock, &size, sizeof(stat_buf.st_size), 0);
But in the server you do:
recv(con, &size, sizeof(size), 0);
size is an int, which is 4 bytes. But st_size is off_t, which is presumably 8 bytes. So you're only reading the first 4 bytes of the the size, and leaving the rest to be copied into the file. That's why you end up with 4 extra bytes on the server.
Declare size with the same data type as st_size, rather than int, and your problem should be solved.
Related
I am try to make most basic FTP feature in c language on macOS host mashine.
I use g++ or gcc compiler. I found c example for linux but sendfile is not the same prototype
like macos system support. I fix include with :
#if __APPLE__
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#elif
#include <sys/sendfile.h>
#endif
Interface:
OSX:
int sendfile(int fd, int s, off_t offset, off_t *len, struct sf_hdtr *hdtr, int flags);
Linux:
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
Whole file :
////FTP SERVER WITH TCP
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#if __APPLE__
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#elif
#include <sys/sendfile.h>
#endif
#include <fcntl.h>
/*
OSX:
int sendfile(int fd, int s, off_t offset, off_t *len, struct sf_hdtr *hdtr, int flags);
Linux:
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
*/
int main()
{
int sock_desc, sock_desc2;
socklen_t len;
struct stat obj;
char length[10];
int filehandle;
char choice[100];
int k, i;
char buf[100];
char target[100];
struct sockaddr_in client, server;
memset(&client, 0, sizeof(client));
memset(&server, 0, sizeof(server));
sock_desc = socket(AF_INET, SOCK_STREAM, 0);
if (sock_desc == -1)
{
puts("Error in socket 1");
exit(1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = 8045;
k = bind(sock_desc, (struct sockaddr *)&server, sizeof(server));
if (k == -1)
{
puts("Error in binding");
exit(1);
}
k = listen(sock_desc, 5);
if (k == -1)
{
puts("Error in listening");
exit(1);
}
len = sizeof(client);
sock_desc2 = accept(sock_desc, (struct sockaddr *)&client, &len);
if (sock_desc2 == -1)
{
puts("Error in socket2");
exit(1);
}
while (1)
{
k = recv(sock_desc2, buf, 100, 0);
if (k == -1)
{
puts("Error in receive");
exit(1);
}
for (i = 0; i < 4; i++)
{
choice[i] = buf[i];
}
choice[i] = '\0';
puts("");
puts(choice);
puts("");
if (strcmp(choice, "LIST") == 0)
{
system("ls -al>list.txt");
filehandle = open("list.txt", O_RDONLY); //
stat("list.txt", &obj); //
sprintf(length, "%d", (int)obj.st_size);
puts("sending size of file");
k = send(sock_desc2, length, strlen(length), 0);
if (k == -1)
{
printf("send failed");
exit(1);
}
puts("send entire file");
k = sendfile(sock_desc2, filehandle, NULL, obj.st_size);
if (k == -1)
{
printf("file sendingfailed");
exit(1);
}
}
else if (strcmp(choice, "LOAD") == 0)
{
puts("inside load");
strcpy(target, buf + 5);
printf("target file is*%s*\n", target);
memset(&obj, 0, sizeof(obj));
stat(target, &obj);
filehandle = open(target, O_RDONLY);
if (filehandle == -1)
{
puts("Error in opening file for read");
exit(1);
}
sprintf(length, "%d", (int)obj.st_size);
k = send(sock_desc2, length, strlen(length), 0);
if (k == -1)
{
puts("Error in sending");
exit(1);
}
k = sendfile(sock_desc2, filehandle, NULL, obj.st_size);
if (k == -1)
{
puts("Error in sending file");
exit(1);
}
}
}
}
UPDATE:
Ok, i wanted to make adaptation, to prepare args for sendfile also for macos. I count on thought 'it is a same compiler and linux and mac are based on UNIX' but it is not enough.
Look's like sockets feature also need totally different source and libs.
Question is simple transfer file in c on macos using gcc compiler.
I found interest imports:
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
Works on macos
I'm coding a client/server, the client simply sends a message to the server that he will print the message.
To do this I used sockets and localhost. Here is the code:
server:
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/un.h>
#include <sys/socket.h>
#include"thpool.h"
#include"functions.h"
#define N 7
#define SERVER_PATH "/tmp/server"
int main(void){
unlink(SERVER_PATH);
struct sockaddr_un stru;
int sock_serv, new_sock;
int opt = 1;
struct sockaddr* cliaddr;
char buff[N];
cliaddr = malloc(sizeof(struct sockaddr));
socklen_t addrlen = strlen((char* )cliaddr);
if((sock_serv = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
printf("socket creation error");
exit(-1);
}
bzero(&stru, sizeof(struct sockaddr_in));
stru.sun_family = AF_UNIX ;
strncpy (stru.sun_path, SERVER_PATH, sizeof(stru.sun_path));
if((bind(sock_serv, (struct sockaddr*) &stru , sizeof(struct sockaddr_un ))) < 0){
perror("bind failed");
exit(EXIT_FAILURE);
}
if(listen(sock_serv, SOMAXCONN) < 0){
perror("listen error\n");
exit(EXIT_FAILURE);
}
if((new_sock = accept(sock_serv, NULL, 0)) < 0){
perror("accept error\n");
exit(EXIT_FAILURE);
}
read(new_sock , buff, N) ;
printf("Server got: %s\n" , buff);
close(sock_serv);
close(new_sock);
unlink(SERVER_PATH);
return 0;
}
and here is the client:
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/un.h>
#include <sys/socket.h>
#include<errno.h>
#include"thpool.h"
#include"functions.h"
#define SERVER_PATH "/tmp/server"
int main(void){
int sock_cl;
struct sockaddr* sa;
socklen_t sa_lenght;
sa = malloc(sizeof(struct sockaddr));
sa_lenght = strlen((char* )sa);
if((sock_cl = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
perror("socket creation error");
exit(EXIT_FAILURE);
}
sa->sa_family = AF_UNIX ;
strncpy (sa->sa_data, SERVER_PATH, sizeof(sa->sa_data));
while (connect(sock_cl , (struct sockaddr*)&sa , (socklen_t)sa_lenght) == -1) {
perror("connection to the server failed");
exit(EXIT_FAILURE);
}
write (sock_cl, "Hello!", 7);
printf("message sended\n");
close(sock_cl);
return 0;
}
I have a problem with the connect() function, the error is "invalid argument". Note that I first executed the server and then the client, so is not that the problem.
This is how you define sa, as a pointer to struct sockaddr.
struct sockaddr* sa;
Here you take the address of the variable sa and cast it to the type of sa.
(struct sockaddr*)&sa
The result is a pointer to pointer to struct sockaddr, which gets brute force cast to pointer to struct sockaddr.
Type-casting is a trap and you got caught in it.
To solve, I recommend using a tutorial on sockets.
I think that when comparing your client and the example client in this tutorial especially the pointer level issue you have created becomes nicely visible:
https://www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/socket.html
Your server and client are both misusing the sockaddr... structures. The error on the server side doesn't affect anything because it is not actually using the faulty sockaddr it allocates, it just leaks. But your client is completely misusing the sockaddr that is passed to connect(), which is why connect() fails.
Try this instead:
server
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/un.h>
#include <sys/socket.h>
#include "thpool.h"
#include "functions.h"
#define N 7
#define SERVER_PATH "/tmp/server"
int main(void){
unlink(SERVER_PATH);
struct sockaddr_un stru;
int sock_serv, new_sock;
ssize_t bufflen;
char buff[N];
if((sock_serv = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
printf("socket creation error");
exit(-1);
}
bzero(&stru, sizeof(stru));
stru.sun_family = AF_UNIX;
strncpy (stru.sun_path, SERVER_PATH, sizeof(stru.sun_path));
if((bind(sock_serv, (struct sockaddr*) &stru, sizeof(stru))) < 0){
perror("bind error");
exit(EXIT_FAILURE);
}
if(listen(sock_serv, SOMAXCONN) < 0){
perror("listen error");
exit(EXIT_FAILURE);
}
if((new_sock = accept(sock_serv, NULL, 0)) < 0){
perror("accept error");
exit(EXIT_FAILURE);
}
bufflen = read(new_sock, buff, N);
if (bufflen < 0) {
perror("read error");
}
else if (bufflen == 0) {
printf("Client disconnected\n");
}
else {
printf("Server got: %.*s\n", (int) bufflen, buff);
}
close(new_sock);
close(sock_serv);
unlink(SERVER_PATH);
return 0;
}
client
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <errno.h>
#include "thpool.h"
#include "functions.h"
#define SERVER_PATH "/tmp/server"
const char *msg = "Hello!";
int main(void){
int sock_cl;
struct sockaddr_un sa;
ssize_t sent;
if((sock_cl = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
perror("socket creation error");
exit(EXIT_FAILURE);
}
bzero(&s, sizeof(sa));
sa.sa_family = AF_UNIX;
strncpy (sa.sa_data, SERVER_PATH, sizeof(sa.sa_data));
if (connect(sock_cl, (struct sockaddr*) &sa, (socklen_t) sizeof(sa)) < 0) {
perror("connect error");
exit(EXIT_FAILURE);
}
sent = write(sock_cl, msg, strlen(msg)+1);
if (sent < 0) {
perror("write error");
}
else {
printf("Message sent: %.*s\n", (int) sent, msg);
}
close(sock_cl);
return 0;
}
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h> //Unable to find all of this header files
#include <signal.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h>
I want to use this header files ion my program and i cannot find it on the internet please provide a source from which i could get them
On windows, socket api is packed into a different set of headers. But the way the windows sockets work (if used in a "portable" way) is pretty much the same as on unix systems. Give or take.
The example code from the other question you linked looks like this on windows:
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
//#include <netinet/in.h>
#include <WinSock2.h>
#include <Ws2tcpip.h>
//#include <sys/wait.h>
//#include <sys/socket.h>
//#include <signal.h>
#include <ctype.h>
//#include <arpa/inet.h>
//#include <netdb.h>
#define PORT 20000
#define LENGTH 512
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
/* Variable Definition */
SOCKET sockfd;
char revbuf[LENGTH];
struct sockaddr_in remote_addr;
/* 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(PORT);
inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr);
ZeroMemory(&(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", PORT);
/* Send File to Server */
//if(!fork())
//{
char* fs_name = "/home/aryan/Desktop/quotidiani.txt";
char sdbuf[LENGTH];
printf("[Client] Sending %s to the Server... ", fs_name);
FILE *fs = NULL;
errno_t err = fopen_s(&fs, fs_name, "r");
if (fs == NULL)
{
printf("ERROR: File %s not found.\n", fs_name);
exit(1);
}
ZeroMemory(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;
}
ZeroMemory(sdbuf, LENGTH);
}
printf("Ok File %s from Client was Sent!\n", fs_name);
//}
/* Receive File from Server */
printf("[Client] Receiveing file from Server and saving it as final.txt...");
char* fr_name = "/home/aryan/Desktop/progetto/final.txt";
FILE *fr = NULL;
err = fopen_s(&fr, fr_name, "a");
if (fr == NULL)
printf("File %s Cannot be opened.\n", fr_name);
else
{
ZeroMemory(revbuf, LENGTH);
int fr_block_sz = 0;
while ((fr_block_sz = recv(sockfd, 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.\n");
}
ZeroMemory(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);
}
}
printf("Ok received from server!\n");
fclose(fr);
}
//close(sockfd);
closesocket(sockfd);
printf("[Client] Connection lost.\n");
return (0);
}
Now you can compare and see what is the same and what is a bit different. Hope that helps you to understand.
In case, you wonder next, why you have linker errors: Link against ws2_32.lib. In contrast to unix systems, where sockets are part of "libc", sockets are factored out into a separate dll in windows.
There are some strange things happening in my client-server application. Please, look at these simple fork client/server:
CLIENT:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/wait.h>
#define IP_SERVER "192.168.1.89"
#define PORT_SERVER 65000
#define BUFFERSIZE 1024
#define NUMFILES 3
double timeElapsed(struct timeval* before, struct timeval* after) {
return after->tv_sec - before->tv_sec + (double) (after->tv_usec - before->tv_usec)/1000000;
}
void getFile(char *request, struct sockaddr_in server) {
char buffer[1024];
int sockProc, res;
int file;
int sizeServ = sizeof(server);
int writeFile;
sockProc = socket(AF_INET, SOCK_STREAM, 0);
if (sockProc < 0) {
printf("Error on creating socket client\n");
perror("");
exit(1);
}
file = open(request, O_CREAT | O_WRONLY, S_IRWXU);
res = connect(sockProc, (struct sockaddr*)&server, (socklen_t)sizeServ);
if (res < 0) {
printf("Error on connecting to server!\n");
perror("");
exit(1);
}
res = send(sockProc, (void*)request, strlen(request), 0);
memset(buffer, 0, sizeof(buffer));
while((res = recv(sockProc, (void*)buffer, sizeof(buffer), 0)) > 0) {
write(file, (void*)buffer, strlen(buffer));
memset(buffer, 0, sizeof(buffer));
}
close(sockProc);
close(file);
return;
}
int main(int argc, char** argv) {
int sockCli, res, i;
struct sockaddr_in server;
int sizeServ = sizeof(server);
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
inet_pton(AF_INET, IP_SERVER, &server.sin_addr);
server.sin_port = htons(PORT_SERVER);
char files[NUMFILES][32];
char nameFile[32];
char command[32] = "rm *.txt";
system(command);
struct timeval begin;
struct timeval end;
pid_t processes[NUMFILES];
for(i = 0; i<NUMFILES; i++) {
memset(nameFile, 0, sizeof(nameFile));
printf("Inserisci nome file (con estensione) da ricevere:\n");
scanf("%s", nameFile);
strcpy(files[i], nameFile);
}
gettimeofday(&begin, NULL);
for(i=0; i<NUMFILES; i++) {
pid_t child = fork();
if(child == 0) {
getFile(files[i], server);
exit(0);
}
else {
processes[i] = child;
continue;
}
}
/*for(i=0; i<NUMFILES; i++) {
waitpid(processes[i], NULL, 0);
}*/
wait(NULL);
gettimeofday(&end, NULL);
printf("Time elapsed on TCP is %f seconds\n", timeElapsed(&begin, &end));
return 0;
}
and the SERVER:
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#define IP_SERVER "192.168.1.89"
#define PORT_SERVER 65000
#define BUFFERSIZE 1024
void execRequest(int* sockCli, struct sockaddr_in* client) {
char buffer[BUFFERSIZE];
char request[BUFFERSIZE];
int res;
memset(request, 0, sizeof(request));
res = recv(*sockCli, (void*)request, sizeof(request), 0);
if(res < 0) {
printf("Error on recv()\n");
perror("");
exit(1);
}
printf("Requested file %s\n", request);
char resource[32] = "files/";
strcat(resource, request);
int file = open(resource, O_RDONLY);
if (file < 0) {
printf("File %s does not exist\n", request);
exit(1);
}
memset(buffer, 0, sizeof(buffer));
while((res = read(file, (void*)buffer, sizeof(buffer))) > 0) {
send(*sockCli, (void*)buffer, strlen(buffer), 0);
memset(buffer, 0, sizeof(buffer));
}
close((*sockCli));
close(file);
free(sockCli);
free(client);
return;
}
int main(int argc, char** argv) {
int sockServ, i, res;
int *sockCli;
struct sockaddr_in server;
struct sockaddr_in* client;
sockServ = socket(AF_INET, SOCK_STREAM, 0);
if(sockServ < 0) {
printf("Error in creating socket\n");
perror("");
exit(1);
}
memset(&server, 0, sizeof(server));
server.sin_addr.s_addr = inet_addr(IP_SERVER);
server.sin_port = htons(PORT_SERVER);
server.sin_family = AF_INET;
int reuse = 1;
res = setsockopt(sockServ, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));
if (res < 0) {
printf("setsockopt() REUSEADDR failed\n");
perror("");
exit(1);
}
res = bind(sockServ, (struct sockaddr*)&server, sizeof(server));
if (res < 0) {
printf("Error on bindind TCP server!\n");
perror("");
exit(1);
}
res = listen(sockServ, 5);
if (res < 0) {
printf("Error on listening TCP server!\n");
perror("");
exit(1);
}
while(1) {
sockCli = (int*)malloc(sizeof(int));
client = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
int sizeClient = sizeof(struct sockaddr_in);
*sockCli = accept(sockServ, (struct sockaddr*)client, &sizeClient);
if ((*sockCli) < 0) {
printf("accept() failed\n");
perror("");
continue;
}
printf("Connected to %s:%d\n", inet_ntoa(client->sin_addr), client->sin_port);
if( !fork() ) {
execRequest(sockCli, client);
exit(0);
}
else
continue;
}
return 0;
}
This is very strange. The processes created by the client don't terminate even if the server closes the sockets and so recv() should return 0 and let client processes exit from the loop. Moreover there's something strange about reading files:
the server simply reads files.txt but in doing this it includes the string ".txt" in the read characters and sends all this mixture to the client...why?
they are simple file mono character like
aaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaa
but the server reads and and sends:
aaaaaaaaaaaaaaaaaa.txt
aaaaaaaaaaaaaaaaaa
can I solve all this?
You can't use strlen(buffer), just because you're loading characters from a text file doesn't mean that buffer will be a valid string unless you take steps to ensure it is. And you don't; there's no termination since you can fill all of buffer with data from the file.
How many times must we play the broken record here on Stack Overflow? Don't cast malloc!
I chalk this error to failure to read the manual(s), to find out what header to include, what a string is (and hence what strlen/strcat/str*{anything}* expects of its input, what printf expects of arguments that correspond to a %s format specifier, etc.) and what read/recv produces.
res = recv(*sockCli, (void*)request, sizeof(request), 0);
if(res < 0) {
printf("Error on recv()\n");
perror("");
exit(1);
}
printf("Requested file %.*s\n", res, request); // NOTE the field width provided by 'res'
By the manual, examples such as res = read(file, (void*)buffer, sizeof(buffer)) supposedly store either an error or a length. The condition ensures that the send code will only execute when it's a length value, so why not use it as one? send(*sockCli, (void*)buffer, res, 0);?
The presense of these problems seems to indicate that your method of learning isn't working. Which book are you reading? Learning C without a book is a bit like learning which berries are poisonous without communication.
The server has to echo the message sent by the client using C program in Linux.I'm using Ubuntu OS (I don't know whether this information is useful or not!). It worked for the first time. But for the second time, it gave 'Error Connection'. I tried changing port numbers. But still it didn't work. Kindly guide me. I'm a beginner.
server.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
int main()
{
int sd, sd1, len, confd, n;
struct sockaddr_in ser, cli;
char msg[50];
if((sd = socket(AF_INET,SOCK_STREAM, 0)) < 0)
printf("\nSocket creation error\n");
bzero(&ser, sizeof(ser));
ser.sin_family = cli.sin_family = PF_INET;
ser.sin_port = htons(10000);
ser.sin_addr.s_addr = htonl(INADDR_ANY);
len = sizeof(ser);
if ((bind(sd, (struct sockaddr*)&ser, len)) < 0) {
printf("\nBind Error");
exit(0);
}
if (listen(sd, 2) == 0) {
if ((sd1 = accept(sd, (struct sockaddr*)&ser, &len)) > 0) {
do {
bzero(&msg, 50);
read(sd1, msg, 50);
//int m=(int)msg;
printf("\nMessage from client:%s\n", msg);
write(sd1, msg, strlen(msg));
if(strcmp(msg, "exit") == 0)
break;
} while(strcmp(msg, "exit") != 0);
}
}
}
*strong text*client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
int main()
{
int sd, n, len;
struct sockaddr_in ser, cli;
char text[50];
if ((sd = socket(AF_INET,SOCK_STREAM, 0)) < 0)
printf("\nSocket creation error\n");
bzero(&ser, sizeof(ser));
ser.sin_family = cli.sin_family = PF_INET;
ser.sin_port = htons(10000);
ser.sin_addr.s_addr = htonl(INADDR_ANY);
len = sizeof(ser);
if ((connect(sd, (struct sockaddr*)&ser, len)) < 0) {
printf("\nError connection");
exit(0);
}
while(1) {
strcpy(text, " ");
printf("\nEnter data which is to be sent:");
scanf("%s", text);
write(sd, text, strlen(text));
read(sd, text, 50);
printf("\nEcho msg from server:%s", text);
if (strcmp(text, "exit") == 0)
break;
}
close(sd);
}
Can your client really connect to any address?
ser.sin_addr.s_addr=htonl(INADDR_ANY);
Most likely you meant to connect to a specific server:
ser.sin_addr.s_addr=inet_addr("127.0.0.1");