Java程序辅导

C C++ Java Python Processing编程在线培训 程序编写 软件开发 视频讲解

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439
TCP_Prog_lab · Wiki · comp3310 / Computer Networks · GitLab Skip to content Projects Groups Snippets Help Loading... Help Support Keyboard shortcuts ? Submit feedback Contribute to GitLab Sign in Toggle navigation C Computer Networks Project overview Project overview Details Activity Releases Repository Repository Files Commits Branches Tags Contributors Graph Compare Issues 0 Issues 0 List Boards Labels Milestones Analytics Analytics Repository Value Stream Wiki Wiki Members Members Collapse sidebar Close sidebar Activity Graph Create a new issue Commits Issue Boards Open sidebar comp3310 Computer Networks Wiki TCP_Prog_lab TCP_Prog_lab Last edited by Robert Edwards Mar 22, 2016 Page history TCP Programming Lab Exercise A Simple Internet Relay Chat type server In a previous lab we concentrated on UDP network programming, first writing a UDP client to access an existing UDP server, then writing our own server. In this lab we want to do essentially the same thing, only using TCP instead of UDP. Writing a TCP client is somewhat unnecessary as there is a perfectly good one in telnet() (man 1 telnet). You can experiment with using telnet as a generic TCP client by telnetting to the Web (HTTP) port of "varese": >telnet varese 80 GET /courses/comp3310/lab3.html HTTP/1.0 [stuff returned] (note that you will need to enter the line "GET /courses/comp3310/lab3.html HTTP/1.0" exactly as written, followed by a blank line to get the web server to respond) Your task is to write a simple Internet Relay Chat (IRC) server. Use the "well-known" port 3310 for your IRC server. getaddrinfo () function Previously we have used functions like gethostbyname() etc. to resolve a DNS (or other) IP name into an IP address. This function has been obsoleted (for some time now) by the getaddrinfo() function, which also knows how to deal with IPv6 addresses. Alas, the getaddrinfo() function is, in some ways, somewhat more complex than the other functions, but, at the same time, also simplifies some aspects of a C program, for example, there is no longer any need to fill in a struct sockaddr_in structure before a bind() or a connect() etc. (and no need to use the htons() and htonl() macros!) getaddrinfo() operates on pointers to structures, called struct addrinfo. Typically, one such structure is created for "hints" and a pointer to this structure is created for the result(s). The structure is defined in the getaddrinfo(3) manpage. #define MY_PORT "3310" struct addrinfo hints, *res, *ai; bzero (&hints, sizeof (hints)); hints.ai_family = AF_INET; /* or AF_INET6 ... */ hints.ai_socktype = SOCK_STREAM; /* for tcp */ if ((n = getaddrinfo (host, MY_PORT, &hints, &res))) { error (1, 0, "getaddrinfo: %s", gai_strerror (n)); } sock = socket (res->ai_family, res->ai_socktype, res->ai_protocol); ... if (connect (sock, res->ai_addr, res->ai_addrlen) != 0) { error (1, 0, "..."); } The neat thing here is that the ai_addr component of the struct addrinfo structure is ready to be used by connect() etc. Note that getaddrinfo() can return multiple results (if the hints are not specific enough) and that these results are linked together in a linked list (ai_next component points to the next result structure). It is possible, in such cases, that the first result structure in the list is not the one that is required and so scanning through the list looking for the appropriate result may be necessary. Making the hints as specific as possible will avoid this. A TCP Echo Server Start by modifying your UDP server code (if you have it completed). Use socket() and bind() as above. After the bind(), your server needs to listen(2) on its socket. After listen(), you need to accept(2) a new connection when one comes in. accept() will block until a client attempts to connect, after which it will return a new socket that you can read from/write to. In a loop, read(2) bytes from the socket and then write(2) them back out again until read() returns 0 bytes which indicates End Of File (EOF), at which point the loop should exit, the connection closed and the server can exit. Note that you should close both the **listen()**ing socket and the read/write (connected) socket returned by accept(). Test it by running the server in one window and then using: telnet localhost 3310 in another window to connect to the server. A simple IRC Server part 1 Adapt the simple echo server above to allow a second telnet connection by adding a second accept() after the first one. In your read()/write() loop, write() the data to the second connection as well. Think about how it might be possible to accept the second connection after the server has started echoing data to the first one. Test it as above, but use a third window to open the second telnet connection to your server. Alternatively, have someone else in the lab connect to your server (you will need to know the IP address/local DNS name of your workstation) A simple IRC Server part 2 - using select() The main problem with the above program is that the code cannot control when connections will come in, nor when data will arrive on which connection. We have a problem with asynchronous events and we need to make the program "event-driven". The main mechanism for doing this in Unix is the select() function, and it is in support of this functionality that sockets were devised and made to act like file descriptors. Understanding select() is a little complex, but we will work through it here. In it's simplest form, select() can be made to wait for something to happen on one or more file descriptors (and sockets) and to return when something does happen. In particular, it returns when one of the file descriptors in the read set will not block when a read() is done on it. The idea is to put the select() into a loop and block on it, having it return when one of the file descriptors of interest is ready to do something, instead of blocking on a single read(). A special data type, fd_set, is used to represent the set of file descriptors of interest. Four "macros" can operate on a variable of this data type: FD_ZERO(), FD_SET(), FD_CLEAR() and FD_ISSET(). Before calling select(), we set up a read file-descriptor set with the the file-descriptors we want to know about. Initially, this will just be the socket that we are **listen()**ing on. We don't need to worry about a fd_set for writes or exceptions for this exercise, as we don't expect anything to block on writes or exceptions. Also, we are not interested in timeouts, so leave all the other parameters as NULL. After select() returns (with no error), we use FD_ISSET() to test the read fd_set to see which file-descriptors are "ready". Initially, this will just be the socket we are listening on and the appropriate response is to accept() the connection. One trick is that select() (necessarily) modifies the read file-descriptor set (and the others, if used) and so we need a way to way to keep persistent information about the file-descriptors (sockets) we are interested in. There are several ways to do this: use a "master" fd_set and memcpy() it to the working read file-descriptor set each time around the select() loop keep an array of connections with the sockets of each and scan this array into the working fd_set each time use a linked list of connection structures (more complex, but "nicer" for a serious server) I recommend using the first option initially. Each time a new connection is **accept()**ed, use FD_SET() to add it to the master fd_set. Each time a connection is closed by the client (read() returns 0 bytes), use FD_CLR() to clear the socket from the master fd_set. When data arrives on one connection, the master fd_set must be scanned to work out which connections to write() the data back out to (you can also choose not to echo back out on the incoming connection). Test as above. (an slightly more modern alternative to select() is poll()) Clone repository AUI AdvPktFwding IoTAssignment LinuxToolsLab NAT SSL_prog_lab SSL_prog_lab2 TCP_Prog_lab access control arp arpcommand arpexploits assessment bgp bitsandbytes More Pages