TCP IO multiplexing Select concurrency server-side Linux Socket Programming Primer (3)

Source: Internet
Author: User
Tags set socket

When I write this code, I find that many places are easily mistaken. Select may have an error, return-1.

Like what

int  fd_isset (int fd,fd_set *fdset), void fd_clr (int fd,fd_set *fdset), void fd_set (int fd,fd_set *fdset); void Fd_zero (int fd,fd_set *fdset);

Several of the macros here are incoming pointers, not value passing.

The SELECT function is declared as follows:
int select (int maxfdp1,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);

Usage:

1. First define good fd_set structure, and use macro Fd_zero to clear 0 processing.

2. Bind the struct and the LISTENFD with Fd_set.

3. Call SELECT. (select will always be plugged in here, listening to LISTENFD or SOCKFD (three handshake messages or data coming))

4. Detect if the incoming data is a three-time handshake, and if so, establish a connection.

5. Traverse the socket with a for from zero to detect if the incoming data is a message, and if so, receive it.

The code is as follows:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <netinet/in.h> #include <errno.h> #define Max_liste N_que 10#define max_buff_line 100#define PORT 9999 int create_socket (); int process_data (int sockfd, fd_set *global_rdfs) ; int main (int argc, char **argv) {int LISTENFD, sockfd;int i, maxfd;struct sockaddr_in cli_addr;int cli_addr_len;int err;ch Ar buff[max_buff_line];int bytes;//declares two fdset variables, fd_set global_rdfs,current_rdfs;listenfd = Create_socket ();//Clear 0 Fd_ ZERO (&AMP;GLOBAL_RDFS);//LISTENFD and Global_rdfs are associated. Fd_set (LISTENFD, &global_rdfs); maxfd = Listenfd;cli_addr_len = sizeof (CLI_ADDR); for (;;) {//Because GLOBAL_RDFS should always pay attention to listenfd//in order to ensure that the fd_set structure to read and write after the next for loop can not error//here with an alias. Current_rdfs = global_rdfs;if (err = select (Maxfd + 1, &AMP;CURRENT_RDFS, NULL, NULL, NULL)) < 0) {//program will block in select until data is available Incoming printf ("Select err:%d", err); return-1;} if (Fd_isset (LISTENFD, &CURRENT_RDFS) {//If there is data for three handshake, connect if (SOCKFD = accept (LISTENFD, struct sockaddr *) &cli_addr, &cli_addr_ Len) <0) {perror ("accept error.\n"); return-1;} printf ("Generated a new connection (sockfd:%d) \ n", SOCKFD); FD_CLR (i, &current_rdfs); maxfd = maxfd > sockfd? MAXFD:SOCKFD; Fd_set (SOCKFD, &global_rdfs); continue;} Traverse from 0 to Max, looking for the incoming message data for (i = 0; I <= maxfd; i++) {if (Fd_isset (i, &current_rdfs)) {printf ("Generate New data:");p rintf (" process_data\n ");p rintf (" I Data:%d ", i);
Note that the object of operation here must be global_rdfs.
                   If written as Current_rdfs, then select Error Process_data (i, &global_rdfs);}} return 0;} int process_data (int sockfd, fd_set *global_rdfs) {char buff[max_buff_line];int bytes;bzero (buff, max_buff_line); bytes = recv (SOCKFD, Buff, max_buff_line, 0); if (bytes < 0) {printf ("Recv err:"); return-1;} if (bytes = = 0) {fd_clr (SOCKFD, Global_rdfs), Close (SOCKFD);p rintf ("Recv:null data:"); return 0;} if (!strcmp (buff, "Q")) {//There is a custom small rule here, that is, when the Q is sent out, the connection fd_clr (SOCKFD, Global_rdfs); Close (SOCKFD);p rintf ("quit!\n"); return 0;} Buff[bytes] = ';p rintf ("%s\n", buff); Send (sockfd, buff, bytes, 0); return 0;} int Create_socket () {int listenfd, err;int len;struct sockaddr_in servaddr;int ret, opt = 1;LISTENFD = socket (Af_inet, SOCK _stream, 0); if (LISTENFD < 0) {printf ("Socket ERR:"); return-1;} Change LISTENFD to non-blocking if (ret = setsockopt (LISTENFD, Sol_socket, so_reuseaddr, &opt, sizeof (OPT))) < 0) {printf ("Error , set socket reuse addr Failed "); return-1;} Bzero (&servaddr, sizeof (SERVADDR)); Servaddr.sin_family = Af_inet;servaddr.sin_port = htons (port); servaddr.sin_addr.s_addr = htonl (inaddr_any); len = sizeof (struct SOCKADD r); err = bind (LISTENFD, (struct sockaddr *) &servaddr, Len); if (Err < 0) {printf ("Bind err:"); return-1;} Err = Listen (LISTENFD, Max_listen_que), if (Err < 0) {printf ("Listen err:"); return-1;} return LISTENFD;}

  

TCP IO multiplexing Select concurrency server-side Linux Socket Programming Primer (3)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.