📄 00000004.htm
字号:
bzero(&(dest_addr.sin_zero), 8); /* zero the rest of the struc <BR>t */ <BR> /* don't forget to error check the connect()! */ <BR> connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(struct sockadd <BR>r)); <BR> . <BR> . <BR> . <BR>Again, be sure to check the return value from connect()--it'll return -1 on <BR>error and set the variable errno. <BR>Also, notice that we didn't call bind(). Basically, we don't care about our <BR>local port number; we only care where we're going. The kernel will choose a <BR>local port for us, and the site we connect to will automatically get this <BR>information from us. No worries. <BR>---------------------------------------------------------------------------- <BR> <BR>10. listen()--Will somebody please call me? <BR>Ok, time for a change of pace. What if you don't want to connect to a remote <BR> <BR>host. Say, just for kicks, that you want to wait for incoming connections <BR>and handle them in some way. The process is two step: first you listen(), <BR>then you accept() (see below.) <BR>The listen call is fairly simple, but requires a bit of explanation: <BR> int listen(int sockfd, int backlog); <BR>sockfd is the usual socket file descriptor from the socket() system call. <BR>backlog is the number of connections allowed on the incoming queue. What <BR>does that mean? Well, incoming connections are going to wait in this queue <BR>until you accept() them (see below) and this is the limit on how many can <BR>queue up. Most systems silently limit this number to about 20; you can <BR>probably get away with setting it to 5 or 10. <BR>Again, as per usual, listen() returns -1 and sets errno on error. <BR>Well, as you can probably imagine, we need to call bind() before we call <BR>listen() or the kernel will have us listening on a random port. Bleah! So if <BR> <BR>you're going to be listening for incoming connections, the sequence of <BR>system calls you'll make is: <BR> socket(); <BR> bind(); <BR> listen(); <BR> /* accept() goes here */ <BR>I'll just leave that in the place of sample code, since it's fairly <BR>self-explanatory. (The code in the accept() section, below, is more <BR>complete.) The really tricky part of this whole sha-bang is the call to <BR>accept(). <BR>---------------------------------------------------------------------------- <BR> <BR>11. accept()--"Thank you for calling port 3490." <BR>Get ready--the accept() call is kinda weird! What's going to happen is this: <BR> <BR>someone far far away will try to connect() to your machine on a port that <BR>you are listen()'ing on. Their connection will be queued up waiting to be <BR>accept()'ed. You call accept() and you tell it to get the pending <BR>connection. It'll return to you a brand new socket file descriptor to use <BR>for this single connection! That's right, suddenly you have two socket file <BR>descriptors for the price of one! The original one is still listening on <BR>your port and the newly created one is finally ready to send() and recv(). <BR>We're there! <BR>The call is as follows: <BR> #include <sys/socket.h> <BR> int accept(int sockfd, void *addr, int *addrlen); <BR>sockfd is the listen()'ing socket descriptor. Easy enough. addr will usually <BR> <BR>be a pointer to a local struct sockaddr_in. This is where the information <BR>about the incoming connection will go (and you can determine which host is <BR>calling you from which port). addrlen is a local integer variable that <BR>should be set to sizeof(struct sockaddr_in) before its address is passed to <BR>accept(). Accept will not put more than that many bytes into addr. If it <BR>puts fewer in, it'll change the value of addrlen to reflect that. <BR>Guess what? accept() returns -1 and sets errno if an error occurs. Betcha <BR>didn't figure that. <BR>Like before, this is a bunch to absorb in one chunk, so here's a sample code <BR> <BR>fragment for your perusal: <BR> #include <string.h> <BR> #include <sys/types.h> <BR> #include <sys/socket.h> <BR> #define MYPORT 3490 /* the port users will be connecting to */ <BR> #define BACKLOG 10 /* how many pending connections queue will hold * <BR>/ <BR> main() <BR> int sockfd, new_fd; /* listen on sock_fd, new connection on new_fd <BR>*/ <BR> struct sockaddr_in my_addr; /* my address information */ <BR> struct sockaddr_in their_addr; /* connector's address information */ <BR> <BR> int sin_size; <BR> sockfd = socket(AF_INET, SOCK_STREAM, 0); /* do some error checking! <BR> */ <BR> my_addr.sin_family = AF_INET; /* host byte order */ <BR> my_addr.sin_port = htons(MYPORT); /* short, network byte order * <BR>/ <BR> my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */ <BR> bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct <BR> */ <BR> /* don't forget your error checking for these calls: */ <BR> bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)); <BR> listen(sockfd, BACKLOG); <BR> sin_size = sizeof(struct sockaddr_in); <BR> new_fd = accept(sockfd, &their_addr, &sin_size); <BR> . <BR> . <BR> . <BR>Again, note that we will use the socket descriptor new_fd for all send() and <BR> <BR>recv() calls. If you're only getting one single connection ever, you can <BR>close() the original sockfd in order to prevent more incoming connections on <BR>the same port, if you so desire. <BR> <BR>--------------------------------------------------------------------------- <BR>- <BR>12. send() and recv()--Talk to me, baby! <BR>These two functions are for communicating over stream sockets or connected <BR>datagram sockets. If you want to use regular unconnected datagram sockets, <BR>you'll need to see the section on sendto() and recvfrom(), below. <BR>The send() call: <BR> int send(int sockfd, const void *msg, int len, int flags); <BR>sockfd is the socket descriptor you want to send data to (whether it's the <BR>one returned by socket() or the one you got with accept().) msg is a pointer <BR> <BR>to the data you want to send, and len is the length of that data in bytes. <BR>Just set flags to 0. (See the send() man page for more information <BR>concerning flags.) <BR>Some sample code might be: <BR> char *msg = "Beej was here!"; <BR> int len, bytes_sent; <BR> . <BR> . <BR> &n
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -