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");
Related
As the title stated - any atempts made by the serverside to send data back to the client result in an imediate crash (segmentation fault). This is a simple tcp chat app - and I am only looking to send strings bidirectionaly between client and server.
Server side below - the chat() function handles communication , after calling fgets , inputting my string , and attempting to send the data - I get an immediate (segmentation fault) and crash.
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <ifaddrs.h>
#define SA struct sockaddr
int chat(int sockfd, int port) {
for (;;) {
char *buffer_send;
char *buffer_recv;
recv(sockfd, buffer_recv, port , 0);
printf("%s", buffer_recv);
printf(":"); fgets(buffer_send, 512, stdin);
char* exit_func;
exit_func = strstr(buffer_send, "exit");
if (exit_func = strstr(buffer_send, "exit")) {
close(sockfd);
return 0;
} else {
send(sockfd, buffer_send, 512, 0);
}
}
}
int main () {
int server_socket, new_socket, c;
struct sockaddr_in socket_address, client;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
printf("socket creation failed! \n");
return 1;
} printf("socket created! \n");
socket_address.sin_addr.s_addr = inet_addr("192.168.0.10");
socket_address.sin_family = AF_INET;
socket_address.sin_port = (8003);
if( bind(server_socket,(struct sockaddr *)&socket_address , sizeof(socket_address)) < 0) {
printf("bind failed! \n");
return 1;
} printf("bind done! \n");
listen(server_socket , 3);
printf("Waiting for incoming connections...\n");
c = sizeof(struct sockaddr_in);
new_socket = accept(server_socket, (struct sockaddr *)&client, (socklen_t*)&c);
if (new_socket<0) {
printf("accept failed\n");
return 1;
} printf("connection accepted!\n");
chat(new_socket, socket_address.sin_port);
return 0;
}
however the same way of sending data on my client seems to work fine (without crashing while trying to send data):
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <ifaddrs.h>
int chat(int sockfd, int port) {
for (;;) {
char *buffer_send;
char *buffer_recv;
printf(":"); fgets(buffer_send, 512, stdin);
char* exit_func;
exit_func = strstr(buffer_send, "exit");
if (exit_func = strstr(buffer_send, "exit")) {
close(sockfd);
return 0;
} else {
send(sockfd, buffer_send, 512, 0);
}
recv(sockfd, buffer_recv, port , 0);
printf("%s", buffer_recv);
}
}
int main () {
int target_socket;
struct sockaddr_in target_server;
target_socket = socket(AF_INET, SOCK_STREAM, 0);
if (target_socket == -1) {
printf("socket creation failed!\n");
return 1;
} printf("socket created!\n");
target_server.sin_addr.s_addr = inet_addr("192.168.0.10");
target_server.sin_family = AF_INET;
target_server.sin_port = (8003);
if (connect(target_socket , (struct sockaddr *)&target_server , sizeof(target_server)) < 0) {
printf("connection failed!\n");
return 1;
} printf("connected!\n");
chat(target_socket, target_server.sin_port);
return 0;
}
You did not allocated the room for incoming messages, the same for the buffer you want to send. I expect to do some char buffer_send[512 + 1] = {}; and char buffer_recv[512 + 1] = {}; to make some place for the message content.
The + 1 is added for the extra safety, to not overwrite the NULL terminator when the message received is large enough to fill the entire allocated buffer.
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;
}
I have made a Socket server and client.the client selects the pdf file and sends it to the server.This code runs perfectly on local machine i.e Server and client run on same host,the file is transfered on the server side and opens up with the content but when i run server and client on different hosts i encounter the following problem the Server is unable to quit and file transfered is getting overwritten at the server side,thus unable to show file content,like if i am sending a 240 kb file from client the file received at the server is of 2 GB.
I am programming in qt creator,and the client is a Gui application that also runs Socket client code while server is a console project.
This is server.cpp
#include <QtCore/QCoreApplication>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define Size 2048
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int s, fd, len;
struct sockaddr_in my_addr;
struct sockaddr_in remote_addr;
socklen_t sin_size;
char buf[BUFSIZ];
FILE *fp = fopen("/home/D.A.D19/Desktop/Filecopy/Q7Basic_essentials.pdf","a+");
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = inet_addr("192.168.103.128");
my_addr.sin_port = htons(8000);
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
qWarning("socket");
return 1;
}
if (bind(s,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)
{
qWarning("bind");
return 1;
}
listen(s, 5);
sin_size = sizeof(struct sockaddr_in);
if ((fd =accept(s,(struct sockaddr *)&remote_addr,&sin_size)) < 0)
{
qWarning("accepted client %s\n", inet_ntoa(remote_addr.sin_addr));
return 1;
}
len = send(fd, "Welcome to my server\n", 21, 0);
while(1)
{
len = recv(fd,buf,Size,0);
The problem is here
if (strcmp(buf,"quit") == 0){
qWarning("Connection terminated");
break;
}
fwrite(buf,Size,1, fp);
memset(buf,0,Size);
}
fclose(fp);
close(fd);
close(s);
return a.exec();
}
This is Client.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QPushButton>
#include <QFileDialog>
#include <QLineEdit>
#include <QString>
#include <QtCore/QCoreApplication>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SIZE 2048
QString Path;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QLabel *label1 = new QLabel(this);
label1->setText("FileName");
label1->setGeometry(15,25,70,30);
label1->show();
QPushButton *pushbutton = new QPushButton(this);
pushbutton->setText("Browse");
pushbutton->setGeometry(180,28,90,25);
pushbutton->show();
QObject::connect(pushbutton,SIGNAL(clicked()),this, SLOT(browse()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::browse()
{
int s, len;
struct sockaddr_in remote_addr;
char buf[BUFSIZ];
memset(&remote_addr, 0, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_addr.s_addr = inet_addr("192.168.103.128");
remote_addr.sin_port = htons(8000);
QLineEdit *line = new QLineEdit(this);
line->setGeometry(82,28,90,25);
QString filename = QFileDialog::getOpenFileName(this,tr("Find files"),
"/home/D.A.D19/Desktop");
line->setText(filename);
line->show();
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
qWarning("socket");
//return 1;
}
if (::connect(s, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) < 0)
{
qWarning("connect");
//return 1;
}
qWarning("connected to server \n");
len = recv(s, buf, BUFSIZ, 0);
qWarning("%s \n",buf);
buf[len] = '\0';
sprintf(buf, "%s", qPrintable(filename));
FILE *fp = fopen(buf,"r");
while(1)
{
if(feof(fp))
{
strcpy(buf,"quit");
send(s,buf,SIZE,0);
break;
}
if(!feof(fp))
{
int count = fread(buf,SIZE,1,fp);
len = send(s, buf,SIZE, 0);
memset(buf,0,SIZE);
}
}
fclose(fp);
::close(s);
return;
}
When you enter the string quit, it will also have the \n.
So when you compare the string, compare like this:
if (strcmp(buf,"quit\n") == 0)
And then execute the code. Now the string will be matched and connection will be terminated.
I am writing a simple client server program using unix domain sockets, but am having issues with the recv() call in my client program.
The program executes as follows:
Server sets up socket and waits for a connection
Client connects and sends a string
Server receives string, and sends string back to client (like an echo)
Client recv() call fails, returning "resource temporarily unavailable"
Client exits
Server waits for another connection
I have also tried using a poll() call in my client to wait for the response from the server.
In this case however, the recv() call simply receives a 0, implying the connection has been closed serverside, which it has not.
I have exhausted google on this error, but no fixes I came accross seem applicable to my code.
I have included my client (with poll() code commented out) and server code below.
I'm probably missing something obvious... but any insight would be greatly appreciated!
Server code:
/*
* testServer.c
*
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <termios.h>
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <linux/spi/spidev.h>
#include <linux/sockios.h>
#include <errno.h>
#define SOCK_PATH "/var/run/ts.serv"
void handleSockIO(int *sockDesc);
int main ()
{
int sock;
struct sockaddr_un sock_addr;
int len, p;
struct pollfd poll_fd[1];
printf("[TS] testServer Started.\r\n");
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
{
perror("[TS]wr_sock creation");
}
else
{
printf("[TS] Created socket descriptor.\r\n");
}
sock_addr.sun_family = AF_UNIX;
strcpy(sock_addr.sun_path, SOCK_PATH);
unlink(sock_addr.sun_path);
len = strlen(sock_addr.sun_path) + sizeof(sock_addr.sun_family);
if (bind(sock, (struct sockaddr *)&sock_addr, len) == -1)
{
perror("[TS]sock bind failed\r\n");
}
else
{
printf("[TS] Bound socket to sock_addr.\r\n");
}
if (listen(sock, 5) == -1)
{
perror("[TS] sock listen fail");
}
else
{
printf("[TS] Socket now listening.\r\n");
}
poll_fd[0].fd = sock;
poll_fd[0].events = POLLIN;
printf("[TS] Waiting for a connection...\r\n");
while (1)
{
p = poll(poll_fd, 1, 1); //Wait for 1 ms for data
if (p == -1)
{
perror("[TS] Poll");
}
else if (p == 0)
{
//printf("Timeout occurred!\n");
}
else
{
if (poll_fd[0].revents & POLLIN)//Data available to read without blocking
{
printf("[TS] Data available on sock..\r\n");
handleSockIO(&sock);
printf("[TS] Waiting for another connection...\r\n");
}
}
}//While(1)
return 0;
}
void handleSockIO(int *sockDesc)
{
int ioSock, n;
socklen_t t;
struct sockaddr_un remote_addr;
char str[15];
memset(str, ' ', sizeof(str));
t = sizeof(remote_addr);
if ((ioSock = accept(*sockDesc, (struct sockaddr *)&remote_addr, &t)) == -1)
{
perror("accept failed\r\n");
}
else
{
printf("[TS] Receiving...\r\n");
n = recv(ioSock, str, sizeof(str), 0);
if (n < 0)
printf("[TS] recvfrom failed: %s\r\n", strerror(errno));
else if(n == 0)
{
printf("[TS] Received %d on ioSock...\r\n", n);
}
else if(n > 0)
{
printf("[TS] Received: %s, which is %d long.\r\n", str, strlen(str));
printf("[TS] Echoing response...\r\n");
if (send(ioSock, str, n, 0) == -1) //Echo str back
{
printf("[TS] send failed: %s\r\n", strerror(errno));
}
else
{
printf("[TS] Send successful\r\n");
}
//============Wait to close IO descriptor=================
int r;
char temp[1]; //Arbitrary buffer to satisfy recv()
do
{
printf("[TS] Waiting for client to close connection...\r\n");
r = recv(ioSock, temp, sizeof(temp), 0);
if (r == 0)
{
printf("[TS] Client closed connection, closing ioSock...\r\n");
close(ioSock);
}
} while (r != 0);
//========================================================
}//if(n>0) else...
}
}
Client code:
/*
* testClient.c
*
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <termios.h>
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <linux/sockios.h>
#include <errno.h>
#define CHAR_BUF_SIZE 15
#define SEND_STRING "Hello!"
#define SOCK_PATH "/var/run/ts.serv"
int main ()
{
char str[CHAR_BUF_SIZE] = {0};
int c, len, n, p;
int s; // s will hold a socket descriptor returned by socket()
struct sockaddr_un serv_addr;
struct pollfd poll_fd[1];
printf("[TC] testClient Started.\r\n");
//===============SOCKET SETUP===============================
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
{
printf("[TC] Socket failed: %s\r\n", strerror(errno));
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sun_family = AF_UNIX;
strcpy(serv_addr.sun_path, SOCK_PATH);
len = strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family);
//==========================================================
// printf("[TC]Trying to connect to TS socket...\r\n");
//===============RESPONSE POLL SETUP========================
poll_fd[0].fd = s;
poll_fd[0].events = POLLIN;
//==========================================================
printf("[TC] Connecting to SOCK_PATH...\r\n");
c = connect(s, (struct sockaddr *)&serv_addr, len);
if (c == -1)
{
printf("[TC] Connection failed: %s\r\n", strerror(errno));
}
else
{
printf("[TC] Connected. Sending string....\r\n");
if (send(s, SEND_STRING, strlen(SEND_STRING), 0) == -1)
{
printf("[TC] send() failed: %s\r\n", strerror(errno));
}
else
{
printf("[TC] Send on SOCK_PATH successful.\r\n");
//Sending complete------------------------------------------------
//Wait for response...
printf("[TC] Waiting for server response...\r\n");
// p = poll(poll_fd, 1, -1); //Wait for a response
//
// if (p == -1)
// {
// perror("[TC] Poll");
// }
// else
// {
// if(poll_fd[0].revents & POLLIN)
// {
n = recv(s, str, sizeof(str), 0);
if (n < 0)
{
printf("[TC] Receive on SOCK_PATH failed: %s\r\n",
strerror(errno));
}
else if(n == 0)
{
printf("[TC] %d Received on SOCK_PATH.\r\n", n);
}
else if(n > 0)
{
printf("[TC] Received %d from SOCK_PATH: %s\r\n",
n, str);
}
// }
// }
}//if(send())
}//if(connect())
printf("[TC] Transction complete, closing connection and exiting.\r\n");
close(s);
return 0;
}
len = sizeof(serv_addr) instead of len = strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family) should solve you problem. Also do not ignore compiler warnings, say n = recv(s, str, strlen(str), 0) with n declared as int and ssize_t returned by recv. It will help you to avoid a future errors.
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.