Java程序辅导

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

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439
Introduction to the Socket API Introduction to the Socket API Tom Kelliher, CS43 Mar. 19, 1996 Background reading: W. R. Stevens, UNIX Network Programming, Chapter 6 (on reserve). A Client-Server Dialogue Sockets API socket() #include #include int socket(int domain, int type, int protocol); Used to create an unamed socket. Must bind or connect. Returns a socket descriptor (small positive int). Returns -1 on error. domain: AF_UNIX --- UNIX domain protocols. AF_INET --- Internet domain protocols. ... type: SOCK_STREAM --- TCP protocol. SOCK_DGRAM --- UDP protocol. SOCK_RAW --- IP protocol. ... protocol: set to 0. Typical call: int sock; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) die(); bind() #include #include int bind(int sd, const struct sockaddr *name, int namelen); Assigns a name (port, etc.) to a socket. Returns 0 if successful, otherwise -1 and look in errno. sd: socket descriptor. name: Pointer to a struct sockaddr_in for Internet sockets. Cast to struct sockaddr *. /* * Socket address, internet style. */ struct sockaddr_in { u_char sin_len; u_char sin_family; /* AF_INET */ u_short sin_port; /* 16 bit port number */ struct in_addr sin_addr; /* IP address */ char sin_zero[8]; }; For a server: sin_port --- desired listen port. Gt 5000. sin_addr --- another struct. Where we're willing to accept connections from. namelen: sizeof name structure. Typical call: struct sockaddr_in server; bzero((char *) &server, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(SERVER_PORT); if (bind(sock, (struct sockaddr *) &server, sizeof(server))) die(); listen() #include #include int listen(int sd, int backlog); Announce willingness to accept connections to socket and a maximum queue length. Returns 0 on success, otherwise -1. sd: socket descriptor. backlog: max size of queue. Maximum is 5. Typical call: int sock; listen(sock, 5); accept() #include #include int accept(int sd, struct sockaddr *addr, int *addrlen); Extract first connection request on queue; blocking if queue is empty. Returns -1 on error, otherwise a non-negative descriptor to use for socket I/O ( read() or write()). sd: socket descriptor. addr: Pointer to a struct sockaddr_in for Internet sockets. Cast to struct sockaddr *. sin_port --- client port. sin_addr --- client IP address. addrlen: addressof sizeof addr structure. Typical call: struct sockaddr_in client; int msgsock, sock, clientLen; clientLen = sizeof(client); if ((msgsock = accept(sock, (struct sockaddr *) &client, &clientLen)) == -1) die(); else { /* Print information about the client. */ if (clientLen != sizeof(client)) die(); printf("Client IP: %s\n", inet_ntoa(client.sin_addr)); printf("Client Port: %hu\n", ntohs(client.sin_port)); connect() #include #include int connect(int sd, const struct sockaddr *name, int namelen); Connect socket to another socket, opening a socket pair communication channel. Returns 0 on success, -1 otherwise. Check errno. sd: socket descriptor. name: Pointer to a struct sockaddr_in for Internet sockets. Cast to struct sockaddr *. sin_port --- server port. sin_addr --- server IP address. namelen: sizeof name structure. Will automatically do a bind and assign an ephemeral port. Use getsockname() to discover the port number. Typical call: struct sockaddr_in server; struct hostent* hp; bzero((char *) &server, sizeof(server)); server.sin_family = AF_INET; if ((hp = gethostbyname(argv[1])) == NULL) { sprintf(buf, "%s: unknown host\n", argv[1]); die(buf); } bcopy(hp->h_addr, &server.sin_addr, hp->h_length); server.sin_port = htons((u_short) SERVER_PORT); /* Try to connect */ if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) pdie("Connecting stream socket"); /* Determine what port client's using. */ clientLen = sizeof(client); if (getsockname(sock, (struct sockaddr *) &client, &clientLen)) pdie("Getting socket name"); if (clientLen != sizeof(client)) die("getsockname() overwrote name structure"); printf("Client socket has port %hu\n", ntohs(client.sin_port)); read() #include ssize_t read(int sd, void* buf, size_t nbytes); Read at most nbytes bytes into buf from sd. Returns -1 on error, 0 on EOF (connection closed), or the actual number of bytes read. sd: socket descriptor. buf: addressof char buffer. nbytes: sizeof buf. Typical call: char buf[BUFFER_SIZE]; int rval, msgsock; bzero(buf, BUFFER_SIZE); if ((rval = read(msgsock, buf, BUFFER_SIZE)) < 0) die(); write() #include ssize_t write(int sd, const void *buf, size_t nbytes); Attempts to write nbytes from buf to sd. Returns -1 on error or the number of bytes actually written. Arguments similar to read(). close() #include int close(int sd); Close socket descriptor sd. Returns -1 on failure, otherwise 0. Byte Ordering Calls #include u_long htonl(u_long hostlong); u_short htons(u_short hostshort); u_long ntohl(u_long netlong); u_short ntohs(u_short netshort); Convert 16- and 32-bit integers between native format (host) and network format. #include #include #include unsigned long inet_addr(const char *ip); char* inet_ntoa(struct in_addr in); inet_addr() converts a char string IP address to its 32-bit network byte-order integer equivalent. inet_ntoa does the opposite. Example Server Program /********************************************************************** * server.c --- Demonstrate a simple iterative server. * Tom Kelliher * * This program demonstrates a simple iterative server. The server * opens a TCP connection on port SERVER_PORT and begins accepting * connections from anywhere. It sits in an endless loop, so one must * send an INTR to terminate it. * * The server reads a message from the client, printing it to stdout. * Then, the server sends a simple message back to the client. **********************************************************************/ #include #include #include #include #include #include #define DATA "Danger Will Roger . . ." #define TRUE 1 #define SERVER_PORT 5001 #define BUFFER_SIZE 1024 /* prototypes */ void die(const char *); void pdie(const char *); /********************************************************************** * main **********************************************************************/ int main(void) { int sock; /* fd for main socket */ int msgsock; /* fd from accept return */ struct sockaddr_in server; /* socket struct for server connection */ struct sockaddr_in client; /* socket struct for client connection */ int clientLen; /* returned length of client from accept() */ int rval; /* return value from read() */ char buf[BUFFER_SIZE]; /* receive buffer */ /* Open a socket, not bound yet. Type is Internet TCP. */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) pdie("Opening stream socket"); /* Prepare to bind. Permit Internet connections from any client to our SERVER_PORT. */ bzero((char *) &server, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(SERVER_PORT); if (bind(sock, (struct sockaddr *) &server, sizeof(server))) pdie("Binding stream socket"); printf("Socket has port %hu\n", ntohs(server.sin_port)); /* Set the listen queue to 5, the maximum. */ listen(sock, 5); /* Loop, waiting for client connections. */ /* This is an interactive server. */ while (TRUE) { clientLen = sizeof(client); if ((msgsock = accept(sock, (struct sockaddr *) &client, &clientLen)) == -1) pdie("Accept"); else { /* Print information about the client. */ if (clientLen != sizeof(client)) pdie("Accept overwrote sockaddr structure."); printf("Client IP: %s\n", inet_ntoa(client.sin_addr)); printf("Client Port: %hu\n", ntohs(client.sin_port)); do { /* Read from client until it's closed the connection. */ /* Prepare read buffer and read. */ bzero(buf, sizeof(buf)); if ((rval = read(msgsock, buf, BUFFER_SIZE)) < 0) pdie("Reading stream message"); if (rval == 0) /* Client has closed the connection */ fprintf(stderr, "Ending connection\n"); else printf("S: %s\n", buf); /* Write back to client. */ if (write(msgsock, DATA, sizeof(DATA)) < 0) pdie("Writing on stream socket"); } while (rval != 0); } /* else */ close(msgsock); } exit(0); } /********************************************************************** * pdie --- Call perror() to figure out what's going on and die. **********************************************************************/ void pdie(const char *mesg) { perror(mesg); exit(1); } /********************************************************************** * die --- Print a message and die. **********************************************************************/ void die(const char *mesg) { fputs(mesg, stderr); fputc('\n', stderr); exit(1); } Example Client Program /********************************************************************** * client.c --- Demonstrate a simple client. * Tom Kelliher * * This program will connect to a simple iterative server and exchange * messages. The single command line argument is the server's hostname. * The server is expected to be accepting connection requests from * SERVER_PORT. * * The same message is sent three times over separate connections, * demonstrating that different ephemeral ports are used for each * connection. **********************************************************************/ #include #include #include #include #include #include #define DATA "The sea is calm tonight, the tide is full . . ." #define SERVER_PORT 5001 #define BUFFER_SIZE 1024 /* prototypes */ void die(const char *); void pdie(const char *); /********************************************************************** * main **********************************************************************/ int main(int argc, char *argv[]) { int sock; /* fd for socket connection */ struct sockaddr_in server; /* Socket info. for server */ struct sockaddr_in client; /* Socket info. about us */ int clientLen; /* Length of client socket struct. */ struct hostent *hp; /* Return value from gethostbyname() */ char buf[BUFFER_SIZE]; /* Received data buffer */ int i; /* loop counter */ if (argc != 2) die("Usage: client hostname"); /* Open 3 sockets and send same message each time. */ for (i = 0; i < 3; ++i) { /* Open a socket --- not bound yet. */ /* Internet TCP type. */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) pdie("Opening stream socket"); /* Prepare to connect to server. */ bzero((char *) &server, sizeof(server)); server.sin_family = AF_INET; if ((hp = gethostbyname(argv[1])) == NULL) { sprintf(buf, "%s: unknown host\n", argv[1]); die(buf); } bcopy(hp->h_addr, &server.sin_addr, hp->h_length); server.sin_port = htons((u_short) SERVER_PORT); /* Try to connect */ if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) pdie("Connecting stream socket"); /* Determine what port client's using. */ clientLen = sizeof(client); if (getsockname(sock, (struct sockaddr *) &client, &clientLen)) pdie("Getting socket name"); if (clientLen != sizeof(client)) die("getsockname() overwrote name structure"); printf("Client socket has port %hu\n", ntohs(client.sin_port)); /* Write out message. */ if (write(sock, DATA, sizeof(DATA)) < 0) pdie("Writing on stream socket"); /* Prepare our buffer for a read and then read. */ bzero(buf, sizeof(buf)); if (read(sock, buf, BUFFER_SIZE) < 0) pdie("Reading stream message"); printf("C: %s\n", buf); /* Close this connection. */ close(sock); } exit(0); } /********************************************************************** * pdie --- Call perror() to figure out what's going on and die. **********************************************************************/ void pdie(const char *mesg) { perror(mesg); exit(1); } /********************************************************************** * die --- Print a message and die. **********************************************************************/ void die(const char *mesg) { fputs(mesg, stderr); fputc('\n', stderr); exit(1); } Thomas P. Kelliher Mon Mar 18 22:35:52 EST 1996 Tom Kelliher