Why does socket() return an integer? [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I know that socket() returns a handle (an integer one) for the communication instance, like a file descriptor.
I think that (to me at least) it would have made more sense if it returned an opaque pointer (like FILE* from fopen()), But an integer? How the implementation manages to work using this integer value to differentiate between a communication instance and the other?
(Same thing applies to open() I think?)

How the implementation manages to work using this integer value to differentiate between a communication instance and the other?
The details depend on the implementation, but it's safe to assume that the operating system maps the file handle to the appropriate chunk of data. Exactly what the integer means doesn't matter -- it could be an index into an array, a number chosen at random and used as an identifier, or something else. All that matters in your code is that the number represents a specific file or socket.
The integer that's returned by socket() is a file descriptor, i.e. a value that refers to a specific FILE data structure. It's often said of Unix that "everything is a file" because the file system is used as an interface to many resources including disk-based files, pipes, devices like printers and terminals, and network connections. Functions that create new file handles, such as open(), accept(), pipe(), and socket(), are expected to return the associated file descriptor.

Related

Difference between "file pointer", "stream", "file descriptor" and ... "file"?

There are a few related concepts out there, namely file pointer, stream and file descriptor.
I know that a file pointer is a pointer to the data type FILE (declared in e.g. FILE.h and struct_FILE.h).
I know a file descriptor is an int, e.g. member _fileno of FILE (and _IO_FILE).
As for the subtle difference between stream and file, I am still learning.
But from here, I am not clear if there is yet another type of entity to which the "file status flags" apply.
Concretely, I wouldn't know if "file status flags" apply to a FILE, to a file descriptor, or what.
I am looking for official references that show the specifics.
Related:
What's the difference between a file descriptor and file pointer?
Whats is difference between file descriptor and file pointer?
What is the concept behind file pointer or the stream pointer?
Specification of file descriptors (I asked this)
difference between file descriptor and socket file descriptor
File Handle
When you visit a web site for the first time, the site might provide your browser with a cookie. The value of this cookie will automatically be provided to the web site on future requests by the browser.
The value of this cookie is likely gibberish to you, but it has meaning to that one specific web server. It's called a session id, and it's a key to look up a record in some kind of database. This record is called a session.
Sessions allow the web server to react to one request based on earlier requests and the consequences of earlier requests. For example, it allows the server to know that the browser provided credentials to the server in an earlier request, and that these credentials were successfully authenticated. This is why you don't need to resupply your credentials every time you want to post/vote/edit as a specific user on StackOverflow.
The cookie's value, the session id, is an opaque value. It doesn't have any meaning to you. The only way it's useful is by providing it back to the web server that gave it to you. Giving it to another web server isn't going to achieve anything useful. It's just a means of identifying a resource that exists in another system.
When that other system is an operating system, we call these resource-identifying opaque values "handles". This is by no means the only time the word handle is used this way, but it's the most common. In much the same way that a session id cookie provides the web server a way of linking web requests together, a handle provides the OS a way of linking system calls together. There are handles for all kinds of resources. There are window handles. There are handles for allocated memory buffers. And there are file handles.
By using the same file handle across multiple calls to read or write, the OS knows where the previous one left off and thus from where to continue. It also knows that you have access to the file from which you are reading or to which you are writing because those checks were done when the file was opened.
File handles aren't just for plain files. A file handle can also reference a pipe, a socket, or one of a number of other things. Once the handle is created, you just have to tell the OS you want to read from it or write to it, and it will use the handle to look up the information it needs to do that.
File Descriptor
This is the name given to file handles in the unix world. open(2) is said to return a file descriptor. read(2) is said to take a file descriptor.
FILE* aka FILE Pointer aka File Pointer
This is also a file handle. But unlike a file descriptor, it's not from the OS. A FILE* is a C library file handle. You can't pass a FILE* to read(2) (a system call) any more than you can pass a file descriptor to fread(3) (a C library function).
You should never access the members of FILE, assuming it even has any. Like all handles, it's meant to be opaque to those receiving it. It's meant to be a box into which you can't see. Code that breaks this convention isn't portable and can break at any time.
Most C library file handles reference an object that includes a file descriptor. (Ones returned by fmemopen and open_memstream don't.) It also includes support for buffering, and possibly more.
File Status Flags
This is not a term you will ever need to use. It's my first time hearing it. Or maybe I just forgot hearing it because it's not important. In the linked document, it's used to refer to a group of constants. Various system calls can be provided some combinations of some of the constants in this group for certain arguments. Refer to the documentation of each system to see what flags it can accept, and what meanings those flags has to it.
Stream
Earlier, I compared file handles to session ids. If a session id allows a web server to look up a session, what is a file handle used to look up? The documentation for the C library I/O functions calls it a stream.
A stream is a loose term that usually refers to a sequence of indeterminate length. It's a term commonly used in communication to refer to the data being communicated between a writer/sender/producer and a reader/receiver/consumer.
A stream is accessed sequentially, whether it's out of necessity or because it's convenient. The possibility of jumping to a different point in the stream doesn't automatically disqualify the use of the term. Like I mentioned above, it's a loose term.
The length of a stream is often unknown. It might be even be unknown to the sender. Take for example a task producing a stream on the fly, possibly from other streams. A stream could even be infinitely long. Sometimes, the length of the stream is knowable, but simply disregarded. And sometimes, the length is known but not in usable units. A program reading lines of variable length from a stream probably can't do anything useful with the length of the stream in bytes.
Take two programs communicating via a pipe like in cat <file1 | cat >file2. We can refer to the data going through the pipe as a stream. The sender may or may not know how many bytes/lines/messages it will eventually send. The sender will send some bytes and later some more, until it eventually signals that no more will follow. The reader often has no idea how many bytes/lines/messages will eventually be sent by the producer. It will get some bytes and later some more, until it's eventually notified that the end of the stream has been reached.
Sometimes, it's more about how the data is treated. For example, reading from a file is often treated as reading from a stream. While it's possible to obtain the length of a file, this information is often disregarded. Instead, the programs that disregard this information just keeps pulling bytes or lines from the file handle until it receives an indication that it reached the end of the stream.
Random access is an example of a file not being treated as a stream. Random access refers to the practice of retrieving data from arbitrary locations of the file. One might do this when one has an index of what's found in the file. An index is some mapping between a key and the location of the item identified by that key in the file. For example, if I know the data pertaining to a user is found at a certain location in a file, I can request that portion of the file from the OS rather than reading the file from the start.

Which approach is is better for talking between two process in c? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I have two different applications.I have to inform application_1 from application_2 that application_1 have to do some operation.(should call a function).
I can write some message 'take_action' in a text file from application_2 and application_1 will check that text file for 'take_action' on a regular interval.After getting 'take_action' it will call corresponding function and will write 'action_taken' to the text file.
I can use pipe or shared memory instead of file.
I can pass signal from application_2 through kill command (kill -SIGHUP) and call required function if SIGHUP signal comes to application_1.
Sample code for approach 1 and 3 are as follows.
approach_1:
in application_2:
fprintf(fp, "take_action");
in application_1:
int rd = read(filedReading, lineText, 13);
if (strcmp(lineText, "take_action") == 0)
{
reloadRule(); //calling required function
}
approach_3:
in application_2:
system("kill -SIGHUP");
in application_1:
void sig_handler(int signo)
{
switch(signo) {
case SIGUSR1:
opt_debug = opt_debug ? 0 : 1;
break;
case SIGHUP:
log_msg(LOG_NOTICE, "SIGHUP SIGNAL RECEIVED");
reloadRule(); //calling required function
default:
cleanexit(0);
}
Which approach is best for this kind of problem?
Opinion as always:
A temporary file is almost always the wrong thing to do if only 1 machine is involved, and RPC methods exist if you need multiple machines to cooperate.
When it is easy to establish the handle, anonymous pipes work well. You can use socketpair and mkfifo extend the pipe model to a wider set of scenarios.
Shared memory is the way forward when the pipe bandwidth is an issue. You can get a lot of data down a pipe, but it still involves a number of copies of the memory. Setting up a shared memory pool is a pain, but it gives both processes (almost) direct access to an agreed shared memory area, that is incredibly fast for data transfers. Of course you have to get this set up and there are potential synchronisation issues, but you can use your pipes to easily establish the connection or to synchronise the memory pool at a much lower bandwidth.
Signals are very limiting. You can only easily send a single flag, and they all already have reasons for existing, and what happens when "R" decides to use USR1 and USR2 for memory management, so you can't use your code with "R" programs, etc? Message queues extend signals to have a small payload, of course.
If you can use an anonymous pipe, then that's probably the best option.
This is because your ability to use a pipe means that your processes instances are intrinsically linked and started together, otherwise it would be hard to open a pipe between them.
If the processes are started together as a pair, they presumably intend to talk to exactly each other and not any other instances of the same programs, and they are probably expected to exit together. Pipes make this very simple, safe, and straight forward.
If the processes were started independently and you wanted to play matchmaker between various instances that weren't started strictly in pairs, then pipes would not have been an option, and sockets would have been a better fit.

Socket select() Time Switching? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have created 6 Sockets and simultaneously listening to all of them using select. I want to find out how much time does the CPU take switching from 1 socket to another. Does anyone know; if not can someone guide me please on how to compute this problem!
I think you may have misunderstood what the select call is actually doing, the man page for select says the following:
Three independent sets of file descriptors are watched. Those
listed in readfds will be watched to see if characters become
available for reading (more precisely, to see if a read will not
block; in particu- lar, a file descriptor is also ready on
end-of-file), those in writefds will be watched to see if a
write will not block, and those in exceptfds will be watched for
exceptions. On exit, the sets are modified in place to indicate
which file descriptors actually changed status. Each of the three
file descriptor sets may be specified as NULL if no file descriptors
are to be watched for the corresponding class of events.
So when your call to select returns what it will tell you is which, if any, of the file descriptors are (in your case) ready to be read from. It's then up to you to decide which to read and how to read it.
If you can I'd reccomend tracking down a copy of Unix Network Programming (by Stevens, Fenner, Rudoff). This will give you all the background information and example C code that you will ever want on network programming.
Or look at the tutorial here

multiple read processes of the same pipe can all read the same message [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I have some doubts about pipes appreciate help if anyone knows
A pipe can be shared by multiple processes simultaneously allowing these processes exchanging "messages" to each other.
When there are multiple read processes of the same pipe can all read the same message (sent only once and not multiple copies)?
In a multi-threaded environment it is possible that a message sent by a process is corrupted when writing to the pipe?
thanks for listening
Stop thinking about "messages". The pipe accepts a sequence of bytes, and your application is entirely responsible for assigning any structure to the sequence. Each byte written to the pipe can be read exactly once, and not multiple times. If each write to the pipe is a fixed size and smaller than a system specified amount, then the write will be atomic and the data will not be "corrupted" (interleaved with other writes) during the write. However, if any of the readers are reading blocks of a different size, then data may be interleaved on the read end. (eg, a writer writes 64 bytes as one "message", but a reader reads 60 bytes from the pipe. The reader expecting a 64 byte sequence will then get 4 bytes from the tail of one and 60 from the start of another, and your data may appear "corrupted"). It is very easy to get "corrupted" data in a multi-threaded environment. It is possible to ensure that none of the writes are interleaved, but it can be difficult to get it right. Keep the messages small and of a fixed size, and make sure the are written with a single write system call (eg, do not use fprintf on a FILE* with the pipe as the underlying file descriptor.)
Note that I'm using the word "corrupted" in quotes throughout, because I believe you really mean interleaved. The byte sequence that you write will not be corrupt from the system's perspective. You may not get back what you expect, but that is not corruption of the data. Rather, it is a programming error.

what is a file handle and where it is useful for a programmer?

I am learning assembly language along with C. this new chapter I started talks about 'file handles', file handles for screen display and file handles for keyboard input etc. I don't know what is a file handle? I am referring to IBM PC ASSEMBLY LANGUAGE PROGRAMMING by Peter Abel
There is a generic concept generally called a "handle" in the context of computer software APIs. In the comments you have probably found a link to the Wikipedia article on that subject.
You are dealing with a specific implementation of a handle data type -- the IBM PC/DOS file handles returned from the int 0x21 interface. If you would like to learn more about these specific file handles, you might want to consult the book Undocumented DOS, which details the in-memory data structures which allow you to investigate these handles further.
Another specific type of handle is the file descriptor returned from the POSIX-standard interface named open(). This function is implemented in the C run-time library on platforms such as Linux, Windows NT, Mac OS, and many other systems. The integer returned from a call to open() may not be a negative number.
Unless you are running under DOS, your file handles are probably provided by the Windows NT Operating System. These file handles are returned from CreateFile() (which is used to open as well as create files), and the only illegal value for a handle returned from this function is INVALID_HANDLE_VALUE. I.e., the Windows NT API may return what would be considered (via casting) a "negative" integer, although it has opened the file.
In all of these cases, the file handle is used to refer to some data structure that keeps track of how the file is open. One important thing which is tracked is the current file position. The position or pointer is set in POSIX by the lseek() function and is read by the tell() function. Any read() or write() takes place from the position of the current file pointer.
Your program can open the same file under two different handles. In this case, the file pointer for each handle is distinct. Updating the file pointer of one handle using lseek() will not affect the file pointer of the other handle to the same file.
A file handle is an integer value which is used to address an open file. Such handles are highly operating system specific, but on systems that support the open() call, you create a handle like this:
int handle = open( "foo.txt", OTHER_STUFF_HERE );
You can then use the handle with read/write calls. The non-portability of handles mean that most people avoid them and instead use the stream library functions in C, such as fopen, fread, fwrite etc.
A handle is something the kernel uses internally to access some resource. Only the kernel really knows what it means, the user process is only told what value to use when it wants to access this resource. They have another advantage in that file handles can be shared among processes - whereas you can't do this with pointers.
Windows uses handles all over the place... files, bitmaps, device contexts, fonts, etc.

Resources