Implementing a chat program and thus involving majority of networking concepts.
This is what I have thought:
Now, to add to this, there can be things like sharing text/voice/video files etc, but then the focus will be on compression majorly. With the chat program, my intention is to learn the majority of "networking" concepts. What else, can be implemented (in this chat program) which can brush up my "networking" concepts? |
Honestly, it all depends on how far you want to go, Anisha. How far are you really looking to go? :p
You could always implement packet sniffing from another host, and learn how TCP and UDP works, along with how network packets are constructed. Besides your chat program, you also have the protocols themselves to learn about, how they operate, and why they operate. And to be off topic, have you ever received the pictures of my son? :) Cheers, Josh |
Quote:
Actually, it will be helpful if you or someone could list down what are the programming possibilities for this context. Currently I have no idea how to answer your question. I have been reading theory for quite sometime now, and am bored, want to get my hands dirty with programming. Quote:
Thanks. anything, else that pops in your mind, something which you can expect from a "real" chat program? Quote:
to that mail, and also received an acknowledgement from you a long time ago. |
Quote:
It is especially useful if you use UDP for binary streams. If the server keeps a copy of a binary stream packet for a short while, up to some time or memory limit, clients could receive packets asynchronously, out-of-order, and request resends only if they notice they missed a packet. You might wish to add "caching strategy" to binary streams, so that audio and video packets are not really cached on the server at all (since they can be omitted with just a small perceived glitch), but things like file transfers will completely break if you miss a packet in the middle. Another thing is whether you wish to allow for client-to-client direct connections, bypassing the server altogether. It might be useful in some cases, for example when transferring files. On the other hand, the server then loses the opportunity to peek and record such communications. Encryption is something I personally would like. You might wish to look at the OpenSSL library, and its support for certificates and/or public key infrastructure. After handshakes, you could use e.g. Blowfish or Twofish for fast symmetric encryption, using some largeish key (agreed upon during handshake). (Public key based identification should be the simplest option. Consider the way authorized_keys work for SSH connections. Each server has their own (fixed) public key, defined in server configuration, and each client creates a new random key at startup. The server public key should be user-visible, for example as a hex string, so they can save it. Key exchange can be then done by each encrypting a random symmetric key using the others public key; only the private key will be able to decrypt it. User names and passwords used for identification are only sent afterwards.) I would also recommend considering letting users contact either using a native binary protocol, and an XML-based one for browser-based (text-only) clients. Javascript can do asynchronous requests, but both the request and response must be XML. Being able to participate in discussions using only a browser (and a Javascript page) might make testing more fun. Finally, it may be a good idea to consider writing the server end and the clients in different programming languages, especially if you are not developing this alone. It is very easy to fall victim of implicit conventions in a programming language, which will later on make porting very hard or impossible. Or to just use the same structures, and ignore all portability issues "for now". Having one side of the communications written in another language makes you keenly aware of the importance of making sure the communications follow agreed upon rules, and that the rules are easily followed in different languages. I have found that it is useful to first create simplified prototypes (server and client), and test the communication protocol before actual implementation or specifying the comms protocol in detail. |
Quote:
Quote:
Quote:
Networking is one of those things that are easier to learn(well, to get basic understanding) by doing. There is limited number of operations for socket communication, so it'll be faster to search for tutorials instead of asking. Quote:
|
Quote:
There is, in my opinion, also zero need for yet another programmer who can do basic chat clients, but cannot handle the more advanced stuff. However, if you strive for commercial success only, then you are absolutely right, and my suggestions are way too complicated and wasteful. Quote:
I don't like cheap and rickety. I don't like simplified tools. I want my tools to work, and I want to adapt them to fit my workflow. I would concede that having binary stream support in a chat client is overdoing it -- except that we still do not have an ubiquitous client for point-to-point file transfers. USB memory sticks are probably the most common method of moving files between two workstations, even if they are network-connected. When I wrote my suggestion with regards to binary transfers, I was thinking about having a list of "published" files (not directories) in the client, with associated visibility flags and access control lists. If allowed, another client could either directly (if allowed by firewalls in between), or through the server (allowed through firewalls if using e.g. HTTP port, port 80) copy the files. There is real world need for something like this -- and in my mind, it would make the tool complete. Granted, the emphasis would be on file transfers, not on chatting. So, although I understand your viewpoint, SigTerm, I respectfully disagree. |
Thanks very much for the detailed reply, Nominal Animal.
Quote:
Will it not be better if I use TCP for file and text data transfer, and UDP for video/voice transfer. I mean switching between the protocols on run time based on the data? Did I miss a point in your above quote? Quote:
How to participate in discussions using only a browser (and a Javascript page)? Any hints? What am I supposed to read for this? EDIT- Ah! You meant this? http://chat.stackexchange.com/rooms/14/photography EDIT- Quote:
messages between them for a trial? Or you meant anything else by "test the communication protocol"? Quote:
The point is NOT to "chat" through a chat program. The book "Unix network programming" describes all sorts of functions etc. but simply reading them doesn't help, and I am looking for ways to get them implemented somewhere somehow. The point is to face the actual programming problems. I don't wish to spend time on developing GUI and the complex game algorithms. If there are some special networking conditions to be kept in mind for game programming, I'd like to implement them here in the chat program itself. Qt provides wrap ups for all the basic functions, lately I found it difficult to understand what exactly their functions do underneath. Doing this through qt might be helpful, once I get hold of the raw basics. Offtopic: Yesterday I searched for Qt jobs in the major areas in and around Delhi, and to my surprise only 3 companies listed!! |
Quote:
Quote:
Quote:
Quote:
Quote:
|
Quote:
What I tried to suggest was to use a single protocol for binary data streams. Using the protocol I roughly outlined, a "caching policy" on the stream would tell the server how important individual packets in the stream are. After all, the only difference between an audio or video stream and a file transfer is the fact that file transfers will break if you skip a packet. Using UDP for file transfers tends to be a bit faster, because it is inherently one way: send and forget. For TCP, each packet is acknowledged, usually before the next one is sent. Since packet loss is expected to be rare, instead of acknowledging each packet (like TCP does) the client could only request missing packets. The client could decide based on the buffer size it uses, and on the stream type, whether to request missing audio and video packets at all, although the server may not have copies any longer. The server backend would similarly use the "caching policy" on the stream to decide on how long to keep a copy of each packet sent to clients. I guess text streams could use the same packet format, too. All you'd need is a better header structure, one that could specify the recipient of the text message (chatroom, person, recipient list). Using a single protocol for all this makes your socket communications simpler, and easier to code and maintain. Quote:
Being able to do something in real time between say a command-line client, and a web page showing up in the browser, tends to feel interesting. Making sure the data packets travel intact from one protocol to the other also happens to exercise the toughest bits to code in the server backend. If you ignore the silly browser bugs, and concentrate on say open source browsers, you do not need a lot of Javascript to send and receive simple strings (encapsulated in some simple XML) and display them on the page. Quote:
Quote:
It is also much easier to get testers when "taking a quick peek" requires one to install nothing, just go to a specific page. The fact that functionality can be severely limited when using a browser is okay. In my opinion, the days of one solitary developer creating a wonderful piece of software is well and truly over. Testing is not something you do afterwards; it is a natural part of the development process. Quote:
Consider HTTP for example. For a HTTP request, the first line must be of form method path HTTP/version followed by one or more header lines, and an empty line to signify the end of the request header. For HTTP/1.1, a Host: header is required; it tells the server which site (of the possibly many sites hosted on that single IP address) the client wants. Now, this sounds perfect, right? Simple, text-based, quite easy to parse. Well, there is a big problem when you add SSL/TLS (aka HTTPS) into the mix. The problem is that before the SSL/TLS handshake, the client should supply the site name first, in order for the server to select which certificate to show to the client. But the HTTP protocol does not allow that. To workaround this issue, quite complicated scenarios have been developed. They tend to work only in newish browsers, and there are a lot of ancient browsers still in use out there. The end result is that servers that have multiple independent secure sites on them, tend to still require multiple IP addresses, so that the certificate can be chosen based on the IP address the client used to connect, instead of just the host name. It is therefore my belief that developing the communications protocol through diverse testing using different types of prototype clients and/or servers will yield a better result. In doing so, you might end up having to learn some of the weirder tools like tcpdump and strace to monitor the actual data transmitted, and the syscalls the process does. Quote:
Most code examples I've ever seen tend to ignore most error checking (or use assertions instead of gracefully failing or even retrying). Most programmers add that stuff only when forced to. Network is one environment where programmers tend to be forced to, because error conditions are common. Clients can be unexpectedly closed, connectivity may drop, and so on. If your communications routines are not careful, they may stall in some wait loop, waiting for a packet that will never come. If you only create a test program, say a command-line chat client that only accepts ASCII text, you are never going to bother to test it completely enough to tell if your communications routines are actually robust, or just good enough. Testing something like that is just too dull. Some programmers tend to be satisfied at good enough; it is certainly a commercially viable approach. Another point is that you will learn by doing. If you are creating something for just the sake of learning, the end result may be limited; if you are a typical human, you'll only follow the avenues that really interest you, neglecting the ones that do not. The interaction between users -- or at least testers -- and developers is important; if for nothing else, for the difference in viewpoints. Testers and users see different things in the software. Typically, what users find important, may not feel so to the developers, and vice versa. There is also the importance of getting positive feedback when you develop something. We humans are, after all, social animals. Finally, I must note that just like SigTerm pointed out, my approach is much more strict than what is considered sensible in the commercial world. If you see programming as just a career, you probably should follow SigTerm's advice above instead. I personally don't need commercial quality programmers for anything; I need gurus that can do tools I can rely on, and develop things like OpenSSH and OpenLDAP and sed and grep and awk and the Linux kernel. I see software development in the future fused to customization and workflow optimization, and that will only happen with deep knowledge of the systems being worked on. Because I may be wrong, my advice in this thread may also be wrong. I obviously think I'm right, but I've been wrong before, so .. |
Thanks you Nominal Animal, for the extremely helpful and detailed follow up.
I think I need to start a brain storming thread on the networking project ideas. ;-) |
All times are GMT -5. The time now is 01:41 PM. |