Hello,
the function listen creates a list that memorizes a number of incoming calls through a socket but how do the first call is deleted and the second becomes the first, is it done using accept?
I have read that accept can wait if it finds no calls in the listen list ,is it the same with read and write.I mean if i have used accept and use read while there is no write from the other side of the socket what will happen?If there was a write but not a read and again a write what will happen to the first string?Is the read function in a constant loop until it finds info to read?
accept the first connection and immediately close it.
Yes. You can configure them as non-blocking, so they'll return error instead of making you wait, but they are blocking by default.
I have another question , if i use sd=socket(...) on a process and i want to see this socket from an other process to use it in connect for example how can i do this?Is the variable holding the socket descriptor global ,i mean does every process see it once created?
No, file/socket descriptors are assigned on a per-process basis, so simply passing the descriptor to another process isn't possible. There are methods to do this, but they're more complicated than that - see this recent thread for hints.
I want to create a child process when there is a call in a socket ,how can i know if there is a least one process in the listen list to create the process so that i will not create needless processes?Does listen blocks the process if there are zero elements in the list?
you should use select() to do what you want.
BSD sockets already optimizes this for you.
When you look at the file descriptor in the FD_SET, check if its the listening socket, if it is, then accept a new connection and do what you want.
int sel = select(fdmax+1, &read_fds, NULL, NULL, &tv);
if (sel == -1) {
perror("select()");abort();
} else if (sel) {
// data must be ready
for(i = 0; i <= fdmax; i++) {
if (FD_ISSET(i, &read_fds)) {
if (i == listening_sock) {
/* handle a new connection */
client_sock = accept(listening_sock, (struct sockaddr *) &client_sin, &addr_len);
if (client_sock < 0) {perror("accept failed");abort();}
FD_SET(client_sock, &master); /* add to master fd set */
if (client_sock > fdmax) fdmax = client_sock; /* set max */
} else {
/* read data from client */
read_bytes = recv(i, buffer, expected_data_len, 0);
// do stuff with data from client
} /* end read data from client */
} /* end if FD_SET */
} /* end loop through all fds */
} /* end while loop */
} else {
// no data within tv.tv_sec seconds
continue;
}
if i have a variable for example buf[10] and i then make a fork in the code if i change the buf variable in one process like buf="end" will the buf in the other process change too?
If you are using threading absolutely. You will have to use a mutex.
if (FD_ISSET(fd, &read_fds)) {
pthread_mutex_lock(&buffer_lock);
// write to the buffer here
pthread_mutex_unlock(&buffer_lock);
}
However you can also allocate a buffer for each client in some sort of data structure if you want.