ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I wrote a program which will send a message to multiple clients(i.e, broadcasting) that are connected to a server.Once when the client receives a message from the server ,the client should read a file in the server and display it in the client.The client which responds (i.e, client wants all the data stored in a file from the server )first will be served by the server(i.e,)the server should read the file stored in the server itself and send the information in the file to the client and should stop receiving the further request from other clients.
I wrote the coding for that..But its not working properly.Can somebody plz clear the bug and make my program to work in the way i wanted??
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<netdb.h>
#include<stdlib.h>
int main()
{
struct sockaddr_in serv;
struct addrinfo hints;
int r,sd,nsd,f,w,c,s,snd,lis;
char buffer[12]="hello world\n",buff[100]="YES";
char buf[100];
sd = socket(AF_INET,SOCK_STREAM,0);
printf("Socket descriptor:_%d_\n",sd);
serv.sin_family=AF_INET;
serv.sin_addr.s_addr=inet_addr("10.142.17.123");
serv.sin_port=htons(4005);
s=sizeof(serv);
c=connect(sd,(void *)&serv,s);
if(c==0)
printf("%d_connected_%s",c,buffer);
else
{
printf("%d_%d_Error in connection\n",c,s);
exit(1);
}
while(1)
{
r = read(sd,buffer,sizeof(buffer));
if(r>0)
{
printf("Server Says :%s\n",buffer);
printf("\n...");
w = write(sd,buffer,sizeof(buffer));
printf("\nSay yes...");
break;
}
}
int count = 0;
if ((recv(sd, buf, sizeof buf, 0)) == -1)
perror("p");
printf("\n The no of lines in file is %s", buf);
count = atoi(buf);
while (count != 0)
{
if ((recv(sd, buff, sizeof buff, 0)) == -1)
perror("k");
printf("\n%s", buff);
count--;
}
}
In simple the server broadcasts a message to multiple clients.Whichever client responds first will receive the the datas in the file stored in the server.Plz help me to make this program work.
Use the int socket descriptor (btw, it is not an unsigned int!) that is returned by accept() as a handle to the client that has just connected.
Use the client socket descriptor to begin comm with the client; from your description, it would appear that the client will send a file name that the server should first receive, and then use to open the corresponding file and shoot back the file's contents to the client.
Code:
...
void handleClient(int client_sd);
int main()
{
int server_sd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=htonl(INADDR_ANY);
sin.sin_port=htons(4005);
bind(server_sd, (struct sockaddr*) &sin, sizeof(sin));
listen(server_sd, 5);
int one = 1;
socklen_t oneLen = sizeof(one);
setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, (void*) &one, oneLen);
for (;;)
{
int client_sd = accept(server_sd, 0, 0);
// insert a fork() here if you want to concurrently process
// multiple clients.
handleClient(client_sd);
}
// will never reach here, but for sake of completeness
close(server_sd);
return 0;
}
void handleClient(int client_sd)
{
char filename[512] = {0};
int bytes = recv(client_sd, filename, sizeof(filename), 0);
if (bytes > 0)
{
FILE* fp = fopen(filename, "r");
if (fp)
{
char line[512] = {0};
while (!feof(fp))
{
if ((bytes = fread(line, 1, sizeof(line) - 1, fp)) > 0)
{
send(client_sd, line, bytes, 0);
}
}
}
else
{
const char* bad = "Bad Filename.";
send(client_sd, bad, strlen(bad), 0);
}
}
close(client_sd);
}
If your code turns out to be more complicated that what I have shown above, then it is probably that factor that is causing you the issues you seem to have every day wrt sockets.
Last edited by dwhitney67; 04-10-2009 at 06:42 AM.
Use the int socket descriptor (btw, it is not an unsigned int!) that is returned by accept() as a handle to the client that has just connected.
Use the client socket descriptor to begin comm with the client; from your description, it would appear that the client will send a file name that the server should first receive, and then use to open the corresponding file and shoot back the file's contents to the client.
Code:
...
void handleClient(int client_sd);
int main()
{
int server_sd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=htonl(INADDR_ANY);
sin.sin_port=htons(4005);
bind(server_sd, (struct sockaddr*) &sin, sizeof(sin));
listen(server_sd, 5);
int one = 1;
socklen_t oneLen = sizeof(one);
setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, (void*) &one, oneLen);
for (;;)
{
int client_sd = accept(server_sd, 0, 0);
// insert a fork() here if you want to concurrently process
// multiple clients.
handleClient(client_sd);
}
// will never reach here, but for sake of completeness
close(server_sd);
return 0;
}
void handleClient(int client_sd)
{
char filename[512] = {0};
int bytes = recv(client_sd, filename, sizeof(filename), 0);
if (bytes > 0)
{
FILE* fp = fopen(filename, "r");
if (fp)
{
char line[512] = {0};
while (!feof(fp))
{
if ((bytes = fread(line, 1, sizeof(line) - 1, fp)) > 0)
{
send(client_sd, line, bytes, 0);
}
}
}
else
{
const char* bad = "Bad Filename.";
send(client_sd, bad, strlen(bad), 0);
}
}
close(client_sd);
}
If your code turns out to be more complicated that what I have shown above, then it is probably that factor that is causing you the issues you seem to have every day wrt sockets.
The code u have given me works like the client has to start the interaction first.But what I wanted is like the server should send a message like "Who wants the file??" .This message has to be sent to all the clients that are connected.The client which says "I want" 1st will be given the file data.After that the ip address of the client to which the data is sent has to be stored in a variable.Most importantly the file should be sent to only one client.Plz help me in this.Because i have been struggling with this for the past one week.I am new to Socket programming ,so i couldn't figure out the actual working of the sockets.I wrote the code with a little knowledge abt sockets.
Everybody is going to have different requirements for their socket application. However, the fundamentals never change.
I have stated this before... for a TCP server, at a minimum, it must do the following:
1. Create a socket
2. Bind the socket
3. Configure any socket options (e.g. Reuse address)
4. Listen on the socket
5. Accept client connections
And whatever happens next is application specific.
For the TCP client, at a minimum, the following must be done:
1. Create a socket
2. Bind the socket (optional)
3. Connect to the server
And whatever happens next is application specific.
From your description, "handshaking" needs to take place. Your server is going to send a message to the client; thus the client should initially be in receive-mode... that is, waiting to receive a message.
So within the server, the handleClient() function could be something like:
Code:
void handleClient(int client_sd)
{
const char* fileQuestion = "What file do you want to open?";
int rtn = send(client_sd, fileQuestion, strlen(fileQuestion), 0);
if (rtn == strlen(fileQuestion))
{
char fileName[256] = {0};
rtn = recv(client_sd, fileName, sizeof(fileName) - 1, 0);
if (rtn > 0)
{
// open file
// send() file contents to the client; make sure to terminate if send() fails (e.g. the
// client disconnects prematurely)
}
}
close(client_sd);
}
Since you are planning to handle more than one client, the server should fork() before calling handleClient(). Or alternatively, a multi-threaded application can be developed. For now, I would just stick with the fork() and make sure the child-process terminates after disconnecting the client.
Code:
...
for (;;)
{
int client_sd = accept(server_sd, 0, 0);
if (client_sd > 0 && fork() == 0)
{
// in child process
handleClient(client_sd);
exit(0);
}
// parent continues (essentially, loops back)
}
...
As for the client application, the specific part is the opposite of the server. Initially the client awaits using a recv(), and upon receiving the query, sends back a response filename (maybe derived from user input?), and then enters a loop where it will receive the file contents until the connection is terminated. You will know the connection has been terminated when recv() returns a 0.
You may also want to use select(), but for your needs, it may not be necessary. After all, you are monitoring only one socket descriptor at any particular time.
Your original code has sin_size uninitialized. Unless it just so happens to be sizeof(struct sockaddr_in), you probably won't get any information inserted into their_addr by accept. I'm glad to see you use sizeof their_addr rather than sizeof(their_addr), which is used for sizing type names.
Kevin Barry
...
I'm glad to see you use sizeof their_addr rather than sizeof(their_addr), which is used for sizing type names.
Kevin Barry
I never realized there was a distinction. Can you provide a simple example of where the two sizeof styles would return a different result. I am curious because I tend to always use the sizeof with the parenthesis for easier code reading, and depending on my mood, I either insert the variable or its type.
Everybody is going to have different requirements for their socket application. However, the fundamentals never change.
I have stated this before... for a TCP server, at a minimum, it must do the following:
1. Create a socket
2. Bind the socket
3. Configure any socket options (e.g. Reuse address)
4. Listen on the socket
5. Accept client connections
And whatever happens next is application specific.
For the TCP client, at a minimum, the following must be done:
1. Create a socket
2. Bind the socket (optional)
3. Connect to the server
And whatever happens next is application specific.
From your description, "handshaking" needs to take place. Your server is going to send a message to the client; thus the client should initially be in receive-mode... that is, waiting to receive a message.
So within the server, the handleClient() function could be something like:
Code:
void handleClient(int client_sd)
{
const char* fileQuestion = "What file do you want to open?";
int rtn = send(client_sd, fileQuestion, strlen(fileQuestion), 0);
if (rtn == strlen(fileQuestion))
{
char fileName[256] = {0};
rtn = recv(client_sd, fileName, sizeof(fileName) - 1, 0);
if (rtn > 0)
{
// open file
// send() file contents to the client; make sure to terminate if send() fails (e.g. the
// client disconnects prematurely)
}
}
close(client_sd);
}
Since you are planning to handle more than one client, the server should fork() before calling handleClient(). Or alternatively, a multi-threaded application can be developed. For now, I would just stick with the fork() and make sure the child-process terminates after disconnecting the client.
Code:
...
for (;;)
{
int client_sd = accept(server_sd, 0, 0);
if (client_sd > 0 && fork() == 0)
{
// in child process
handleClient(client_sd);
exit(0);
}
// parent continues (essentially, loops back)
}
...
As for the client application, the specific part is the opposite of the server. Initially the client awaits using a recv(), and upon receiving the query, sends back a response filename (maybe derived from user input?), and then enters a loop where it will receive the file contents until the connection is terminated. You will know the connection has been terminated when recv() returns a 0.
You may also want to use select(), but for your needs, it may not be necessary. After all, you are monitoring only one socket descriptor at any particular time.
Thanx dwhitney I somehow got what i want.Thanx for ur valuable responses.
I never realized there was a distinction. Can you provide a simple example of where the two sizeof styles would return a different result. I am curious because I tend to always use the sizeof with the parenthesis for easier code reading, and depending on my mood, I either insert the variable or its type.
If they work in the opposite situations they should still return the correct values; however, I believe the distinction is a standard. Sometimes your code won't compile if you use the incorrect pattern, at least in my experience. It also makes your code a little more clear.
Kevin Barry
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.