Category Archives: JAVA

Uncaught TypeError: Cannot read property ‘toFixed‘ of null

Error chart:

when making the line chart , the data is obtained through Ajax , that is, clicking different values will display different charts, and then such an error occurs in the process of testing<
refer to several blogs:
ecarts.js report error cannot read property ‘ToFixed’ of null
it’s written very carefully, but it’s useless for my questions here ε=(´ο`*))) Alas

In the process of solving the above problems, the console has a warning there is a chart instance already initialized on the DOM (not in the screenshot above), and I want to know the problem to be solved, so I take a look at Baidu:
1, there is a chart instance already initialized on the DOM
2 Ecart notes – initialization and destruction
although this is not helpful for my problems, it makes me understand ecarts a little more. Let’s talk about the problems I have solved!

In fact, it’s very simple, I suddenly have an idea, try the next result is good
at the beginning, there are data (more than two), and graphics can be drawn
when you click other, the graph will not come out (at this time, there is only one data). After thinking about it, the line chart can be drawn from at least two data, ah!

Solution: there may be only one data

Hystrix fuse of spring cloud system

Problem phenomenon: continuous clicking causes the fusing of hystrix

The solution on the Internet is to adjust the maxqueuesize property. After the modification, the following error still appears. Why does the maxqueuesize property not work?Later, by checking the official documents, we found that hystrix also has a queuesizerejectionthreshold property, which controls the maximum threshold of the queue. By default, hystrix only has five, Therefore, even if we set the maxqueuesize value to be larger, it will not work. Both properties must be configured at the same time

could not be queued for execution and no fallback available

Solution

hystrix:
  threadpool:
    default:
      coreSize: 200 #Maximum number of threads for concurrent execution, default 10
      maxQueueSize: 1000 #Max queue size of BlockingQueue, default -1
      queueSizeRejectionThreshold: 800 #Even if maxQueueSize is not reached, the request will be rejected after reaching the value of queueSizeRejectionThreshold

Maven plugin development report error- plugin:3.2 :descriptor fai

Maven plugin error execution default descriptor of goal org. Apache. Maven plugins:maven-plugin-plugin :3.2:descriptor failed

The above error occurred when writing Maven plug-in.

Solution

Display the version number of the specified Maven plugin plugin in POM. XML

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-plugin-plugin</artifactId>
                <version>3.5.2</version>
            </plugin>
        </plugins>
    </build>

other error
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-plugin-plugin:3.2:descriptor (default-descriptor) on project maven-project: Error extracting plugin descriptor: ‘No mojo definitions were found for plugin
How to Solve
Show the version number of the specified maven-plugin-plugin in pom.xml

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-plugin-plugin</artifactId>
                <version>3.5.2</version>
                <configuration>
                    <!-- Or add a descriptor to the mojo class comment -->
                    <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
                </configuration>
            </plugin>
        </plugins>
    </build>

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:testCompile (default-testCompile) on project xxx: Fatal error compiling: basedir D:\xxx\target\generated-test-sources\test-annotations does not exist -> [Help 1]

Solution
Skip the test during installation

mvn install -DskipTests=true

Notes for migrating Oracle jdk8 to openjdk11

Java 8 upgrade Java 11

Because orcle stopped the free follow-up security update of jdk8, the decision to upgrade JDK to 11 was adopted after the decision.

Specific version:

current version

java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

Target version

java -version
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.2+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.2+9, mixed mode)

Upgrade process:

Download and install jdk11

JDK download
the selection of jdk11 version is: adptopen JDK 11.0.2 + 9
1 https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/tag/jdk-11.0.2+9
Download
https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.2%2B9/OpenJDK11U-jdk_ x64_ windows_ hotspot_ 11.0.2_ 9. Zip
latest or more versions: GitHub view all the released versions of open JDK (change the environment variable to jdk11, if you don’t start a java program such as Tomcat on the command line, you can skip this step, generally you don’t need to use ide on Windows)

Add jdk11: Ctrl Shift Alt + s — & gt; SDKs –> + Select JDK — & gt; Make sure that the compiler of the specified project in the directory is jdk11: Ctrl Shift Alt + S – & gt; Project ——> The project SDK and project SDK level are changed to the newly added 11, and the rest remain unchanged (the project is controlled by Maven’s pom.xml)
update the project compiler to jdk11pom.xml. See the following for the detailed process

Pom.xml transformation

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <release>11</release>
    </configuration>
</plugin> 

This plug-in is used to compile the source code; The configuration in it represents the use of 11 to compile

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <argLine>
            --illegal-access=permit
        </argLine>
    </configuration>
</plugin>

Surefire plug-in is used to execute unit test of an application in the test phase of Maven build life cycle. It will produce two different forms of test results

<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.23.1-GA</version>
</dependency>

The questions are listed as follows:

if the method provided in this paper can not be solved, you can try the following </ H6>
    1. clean the whole project/project and recompile it with Java 11
    1. in idea:
    1. build — build artifacts — all — clean
    1. build — build artifacts — all — build delete the corresponding components under Tomcat/webapps (clear the cache) </ OL>

Question 1

Symptom
resource cannot be resolved to a type
javax. Annotation. Resource
cause
resource class cannot be found; Java 11 has been removed as an alternative solution

Solutions

Add in pom.xml:

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.1</version>
</dependency>

Reference from stack overflow


Question 2

E rror:java : symbol not found
symbol: class resource
location: package javax.annotation

Solution:

        <dependency>
			<groupId>javax.annotation</groupId>
			<artifactId>javax.annotation-api</artifactId>
			<version>1.3.1</version>
		</dependency>   


Question 3

JAXB (Java. XML. Bind) problems are as follows:

Error:(10, 33) java: Package javax.xml.bind.annotation does not exist
Error:(24, 2) java: Symbol not found
  Symbol: Class XmlRootElement
Error:(28, 6) java: Symbol not found
  Symbol: Class XmlElement
  Location: Class com.xxx.xxx.xxxx.xxx.entity.xxx
  .....

Reasons
openjdk11 has deleted some packages. The following is an announcement:

Removal Of Java EE Modules
There used to be a lot of code in Java SE that was actually related to Java EE. It ended up in six modules that were deprecated for removal in Java 9 and removed from Java 11. Here are the removed technologies and packages:)
 
 
the JavaBeans Activation Framework (JAF) in javax.activation
CORBA in the packages javax.activity, javax.rmi, javax.rmi.CORBA, and org.omg.*
the Java Transaction API (JTA) in the package javax.transaction
JAXB in the packages javax.xml.bind.*   ############ This package is the cause of the problem
JAX-WS in the packages javax.jws, javax.jws.soap, javax.xml.soap, and javax.xml.ws.*
Commons Annotation in the package javax.annotation

The corresponding version is as follows:

<!-- Java 6 = JAXB version 2.0   -->
<!-- Java 7 = JAXB version 2.2.3 -->
<!-- Java 8 = JAXB version 2.2.8 -->
<!-- Java 9 = JAXB version 2.3.0 -->

Note: before the project is which version of JDK to introduce which version, for example, I was java8, so I want to introduce the JAXB version of 2.2.8

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.2.8</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.2.8</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.8</version>
</dependency>

Reference from stack overflow


Question 4

Warning: (54,44) newinstance() in Java: Java. Lang. class is obsolete

Solution:

Check the source code of newinstance() in open JDK 11 Java. Lang. class. Some comments are as follows

    /* can be replaced by
     *
     * <pre>{@code
     * clazz.getDeclaredConstructor().newInstance()
     *}</pre>
     */

It can be replaced by the above method

clazz.newInstance();

replace with

clazz.getDeclaredConstructor().newInstance();

Question 5
After starting Tomcat
Artifact upm-web:war: Error during artifact deployment. See server log for details.
View the logs as follows.

19-Mar-2019 09:50:31.061 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class [com.xxx.xxx.xxx.WebContextLoaderListener]
 java.lang.UnsupportedClassVersionError: com/xxx/xxx/xxx/WebContextLoaderListener has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0 (unable to load class [com.xxx.xxx.xxx.WebContextLoaderListener])
	at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2377)
	at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:846)
	...
19-Mar-2019 09:50:31.061 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.listenerStart Skipped installing application listeners due to previous error(s)

Reason
according to the description of exception information (unsupported version of XXX. Class), it means that the current class version to be loaded is 55 (Java 11), which cannot be loaded. The current Java runtime supports 52 (Java 8) versions of. Class files at most
where the java version corresponds to the class version as follows:

J2SE 11 = 55 (0x33 hex),
J2SE 10 = 54 (0x33 hex),
J2SE 9 = 53 (0x33 hex),
J2SE 8 = 52 (0x33 hex),
J2SE 7 = 51 (0x33 hex),
J2SE 6.0 = 50 (0x32 hex),
J2SE 5.0 = 49 (0x31 hex),
JDK 1.4 = 48 (0x30 hex),
JDK 1.3 = 47 (0x2F hex),
JDK 1.2 = 46 (0x2E hex),
JDK 1.1 = 45 (0x2D hex).

It can be seen that the actual cause of the problem is that the program compiled by java8 (Tomcat) calls the program compiled by java11.

Solution:

Using higher version Tomcat 9

Detailed process:

Go to Tomcat official website to download tomcat9, unzip the downloaded zip (modify the Tomcat environment variable and do not use it in the command line, which can be skipped). Modify the Tomcat set in IDE to the newly installed tomcat9. Take idea as an example:

Run edit configurations on the top right — configure on the right side of application server… Click on the top left + add the file location of newly installed tomcat9, OK, confirm to save the modification below, change JRE to newly added JDK 11, save the settings (note whether there are errors in the prompt area below) and run to check whether the configuration is correct


The above is my JDK version upgrade problems. Welcome to add!

Monitoring session to determine whether the user is online or not

Contents of articles

Scenario description session container add session remove session logout session failure

Supplement: listen to the change of session property. Session is independent of other session sharing schemes

Scene description

In the spring boot project, in order to simplify the message module, if there is a new message, write it to the database first. If the user is online, set newmessage flag = true in the session of the user receiving the message. The front end only needs to poll the session each time, and does not need to visit the database each time
the session needs to be obtained according to the user ID, so if the user logs in successfully, call the put method, log out or if the session fails, call remove.

Session container

Stores the session of the logged in user

public class LoggedUserSessionContext{
	//The default capacity is 16, you can set a reasonable initial value according to the number of visits to your site to avoid frequent expansion at the beginning.
    private static Map<Integer, HttpSession> sessionMap = new ConcurrentHashMap<>(128);

    public static HttpSession putIfAbsent(Integer userId, HttpSession session) {
    	// previously logged in a client, then return that session, to achieve multi-party login session sharing
	    return sessionMap.putIfAbsent(userId, session);        
    }

    public static void remove(Integer userId) {
        sessionMap.remove(userId);
    }
 
    public static HttpSession getSession(Integer userId) {
        return sessionMap.get(userId);
    }

}

Add session

After the user logs in successfully, execute the following code snippet

HttpSession session = LoggedUserSessionContext.getSession(user.getId());
            if(session != null){
                //Use the previously logged in id
                SpringUtil.setCookie("JSESSIONID", session.getId(), 60 * 30);
			}else{
				session = SpringUtil.getRequest().getSession();
				session.setAttribute(SessionKey.USER, user);
				LoggedUserSessionContext.putIfAbsent(user.getId(), session);
			}

After successful registration, execute the following code snippet

HttpSession session = SpringUtil.getRequest().getSession();
			session.setAttribute(SessionKey.USER, user);
			LoggedUserSessionContext.putIfAbsent(user.getId(), session);

Remove session

On cancellation

User user = (User)session.getAttribute(SessionKey.USER);
LoggedUserSessionContext.remove(user.getId());
session.invalidate();

When session fails

Use the listener to monitor the implementation of session and implement the HttpSessionListener interface


import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class SessionListener implements HttpSessionListener {

    //Note: HttpServletRequest's getSession() method, if the current request does not correspond to the session will automatically create a session.
    //Using getSession(false) will not create session, if there is no session corresponding to the current request, it will return null.

   
    //New session created if unknown user browsing
    @Override
    public void sessionCreated(HttpSessionEvent event) {

    }

    //session Destroy User offline, logout login
    @Override
    public void sessionDestroyed(HttpSessionEvent event) throws ClassCastException {
        HttpSession session = event.getSession();
        Object userObj = session.getAttribute(SessionKey.USER);
        if(userObj != null){
        	User user = (User)userObj;
        	LoggedUserSessionContext.remove(user.getId());
        }
        
    }

}

Supplement:

Listen for the change of session property


With HttpSessionAttributeListener * * it is not recommended to listen to HttpSessionAttributeListener * * because it is too frequent

import java.util.HashSet;

import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener {

    //注Meaning: HttpServletRequest's getSession() method, if the current request does not correspond to the session will automatically create a session.
    //use getSession(false) will not create session, if there is no session corresponding to the current request, it will return null.

    //add property user login 
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        HttpSession session = httpSessionBindingEvent.getSession();
    }

    //Delete Properties User Logout
    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        logger.info("--attributeRemoved--");
    }

    //Property substitution Information change
    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        
    }

    //New session creation If unknown user browsing
    @Override
    public void sessionCreated(HttpSessionEvent event) {
        HttpSession session = event.getSession();
        MySessionContext.AddSession(event.getSession());
    }

    //session Destroy User offline, logout login
    @Override
    public void sessionDestroyed(HttpSessionEvent event) throws ClassCastException {
        HttpSession session = event.getSession();
        MySessionContext.DelSession(session);
    }

}

Session independence

Instead of sharing sessions, you can use code logic to set pseudo sharing and change the container and data structure where sessions are stored

 private static Map<Integer, List<HttpSession>> sessionMap  = new ConcurrentHashMap<>(128);

In this way, each terminal can use session without affecting each other.

Error:Cannot build artifact xxx:war exploded’ because it is included into a circular dependency

Error:Cannot build artifact xxx:war exploded’ because it is included into a circular dependency solution
IDEA error: Error:Cannot build artifact xxx:war exploded’ because it is included into a circular dependency

How to Solve:
ctrl + alt + shift + s Open project structure (or ctrl alt + a to search for project structure)
Click on the left artifacts and delete the two extra ones, which are
xxx:warxxx:war exploded
Delete is OK

Spring boot real time HTML page

Add the following configuration in application. Properties

spring.thymeleaf.cache=false # close cache

Introduce debugging tools into POM. XML and set it to open

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>

alt + ctrl + S open settings:
Build,Execution,Deployment —— Complier:
Check Build project automatically
ctrl + shift + alt + /:
Check Registry
Check compiler.automake.allow.when.app.running

C language: Implementation of dynamic array initialization, insertion, traversal, deletion and destruction

Initialization of dynamic array

#include <iostream>
using namespace std;
struct dynamicArray{ 
      void **pAddr;
      int m_capacity;
      int m_size;
      }
struct dynamicArray *initdynamicArray(int capacity){ 
         if(capacity<=0) {      
           return 0;
           }  
   struct dynamicArray *array=malloc(sizeof(struct dynamicArray)) 
   if(array=NULL){   
      return 0;
    }   
     array->pAddr=malloc(sizeof(void*)*capacity); 
     array->m_capacity=capacity;   
     array->size=0;    
     return array;
     }

Function series

```void *insert(struct dynamicArray *array,int pos,void *data){
if(array==NULL||data==NULL){
    return 0;
}
if(pos<=0||pos>array->m_size){
     pos=array->m_size;
}
if(array->m_size==array->capacity){
     int newCapacity=array->capacity;
     void **newSpace=malloc(sizeof(void*)*newCapacity);
     memcpy(newSpace,array->pAddr,sizeof(void *)*array->capacity);
     free(array->pAddr);
     array->pAddr=newSpace;
}

for(int i=array->m_size;i<=pos;i--){
     array->pAddr[i+1]=array->pAddr[i];
}

array->pAddr[pos]=data;

void foreach_Dynamicarray(struct dynamicArray *array,void(myPrint)(void*)){
     for(int i=0;i<array->m_size;i++){
     myPrint(array->pAddr[i]);
     }
 }
 void myPrintPerson(void *data){
     struct person *p=data;
     cout<<p->blabla<p->blabuble<endl;
 }

 void remove(struct dynamicArray *array,int pos){
     if(array==NULL||pos<=0||pos>=array->){
      return 0;
   }
   for(int i=array->m_size;i>=pos;i--){
       array->pAddr[i]=array->pAddr[i+1];
   }
 }

 void destroy(struct dynamicArray *array){
    if(array=NULL){
        return 0;
    }
    if(array->pAddr!=NULL){
        free(array->pAddr);
        array->pAddr=NULL;
    }
    free(array);
    array=NULL;
 }

Java will convert Excel to list set or JSON, export excel file to local, excel import and export, easyexcel tool class

Introducing Maven coordinates

        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>        
        <!--easyexcel-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.8</version>
        </dependency>

According to the file path, the excel file is parsed into a list

    /**
     * Parsing Excel files into Lists
     *
     * @param pathName file path (e.g. D:\test\xzh.xlsx)
     * @param head Table header
     * @param <T> generic
     * @return
     */
    public static <T> List<T> upload(String pathName, Class<T> head) {
        List<T> list = new ArrayList<>();
        AnalysisEventListener<T> analysisEventListener = new AnalysisEventListener<T>() {
            // This will be called for every data parsing
            @Override
            public void invoke(T data, AnalysisContext context) {
                log.info("Parsing a piece of data:{}", JSON.toJSONString(data));
                list.add(data);
                // TODO Here you can also manipulate the data
            }

            // All the data parsing is done and will be called
            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                log.info("All data parsing is complete!") ;
                // TODO Here you can also manipulate the data
            }
        };
        EasyExcel.read(pathName, head, analysisEventListener).sheet().doRead();
        return list;
    }

According to the file stream, the excel file is parsed into a list

    /**
     * Parsing Excel files into Lists
     *
     * @param file File
     * @param head table header
     * @param <T> generic
     * @return
     */
    public static <T> List<T> upload(MultipartFile file, Class<T> head) {
        List<T> list = new ArrayList<>();
        AnalysisEventListener<T> analysisEventListener = new AnalysisEventListener<T>() {
            // This will be called every time the data is parsed
            @Override
            public void invoke(T data, AnalysisContext context) {
                log.info("Parsed a piece of data: {}", JSON.toJSONString(data));
                list.add(data);
                // TODO You can also manipulate the data here
            }

            // All the data parsing is done and it will call
            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                log.info("All data parsing is complete!") ;
                // TODO Here you can also manipulate the data
            }
        };
        InputStream inputStream;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            log.error("upload-InputStream-Exception:", e);
            return null;
        }
        EasyExcel.read(inputStream, head, analysisEventListener).sheet().doRead();
        return list;
    }

Download excel file to file path

    /**
     * Excel file download
     *
     * @param pathName File path
     * @param sheetName Worksheet name
     * @param data data
     * @param head Table header
     * @param <T> generic
     */
    public static <T> void download(String pathName, String sheetName, List<T> data, Class<T> head) {
        EasyExcel.write(pathName, head).sheet(sheetName).doWrite(data);
    }

Excel file download to file path response body response

    /**
     * Excel file download
     *
     * @param response response body
     * @param excelName File name
     * @param sheetName Worksheet name
     * @param data data
     * @param head table header
     * @param <T> generic
     */
    public static <T> void download(HttpServletResponse response, String excelName, String sheetName, List<T> data, Class<T> head) {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("UTF-8");
        try {
            String fileName = URLEncoder.encode(excelName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), head).sheet(sheetName).doWrite(data);
        } catch (IOException e) {
            log.error("download-Exception:", e);
        }
    }

GitHub: https://github.com/xxiangzh/xzh-excel/tree/easyexcel

JAVA: Controller exception handling

With the @controlleradvice annotation, @exceptionhandler can specify the subdivision type of the exception on the specified controller

@ControllerAdvice
public class BaseController {

    private static final Logger logger = LoggerFactory.getLogger(BaseController.class);

    /**
     * Parameter type conversion error
     *
     * @param exception error
     * @return error message
     */
   @ExceptionHandler(HttpMessageConversionException.class)
   public String parameterTypeException(HttpMessageConversionException exception){       
        logger.error(exception.getCause().getLocalizedMessage());
        return ResultErr("Type conversion error");
   }

	/**
	 * Uniform exception handling
	 */
	@ExceptionHandler(value = Exception.class)
	@ResponseBody
	public String handlerException(Exception e) {
	    logger.error("Data check failure : errorMessage{"+e.getMessage()+"}");
		return ResultErr(e.getCode(), e.getMessage());
	}
	
}

C++: Implementation of multi-channel IO transfer with select

Basic idea of select

Set LFD as port reuse

The file descriptors that need to be monitored are sent to the kernel for listening through select. When an event occurs, the number of events is returned through select. Then scan the set of file descriptors one by one to process the event.

Include file:

< sys/select.h>

The function structure of select is as follows:

int select(int nfds, fd_ set * readfds, fd_ set *writefds, fd_ set *exceptfds, struct timeval *timeout);

Parameter description

fd_ Set: the structure of file descriptor set. It is a 1024 bitmap. 0 means that there is no event and 1 means that there is an event. The converted format is:
typedef struct
{
long int__ fds_ bits[1024/(8*8))];
}
NFDS: the maximum number of file descriptors being monitored is + 1
readfds: read set is an incoming and outgoing parameter. The incoming parameter is the set of file descriptors that need to be read and monitored, and the outgoing parameter is the changed file descriptor<
writefds: write file descriptor (same as above, incoming and outgoing parameters)
execptfds: exception file descriptor (same as above, incoming and outgoing parameters)
timeout:
0: no blocking, return immediately after scanning
greater than 0: blocking waiting time is long, return immediately when no event occurs before arrival time
null: permanent blocking wait event
Return:
– 1: listening failure
greater than 0: number of events

Correlation bit operation

1. Remove FD from set
void FD_ CLR(int fd,set *set);
2. Judge whether the descriptor is in the set
2_ ISSET(int fd,fd_ set *set);
3. Put descriptors into the set
void FD_ SET(int fd,fd_ Set * set)
4. Empty set
void FD_ ZERO(fd_ set *set)

Advantages and disadvantages of select

Advantages: cross platform, supported on both windows and Linux
disadvantages: it involves copying back and forth between user area and kernel area. When there are many links but few active users, the efficiency is low, and the maximum number of listeners can not exceed 1024.

Select code

Insert code snippet here
#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>	
#include<netinet/in.h>
#include<ctype.h>
#include<sys/socket.h>
#include<sys/select.h>

#include<iostream>
#include<string>

using namespace  std;
int main()
{
    /*1.create socket*/
    int lfd=socket(AF_INET,SOCK_STREAM,0);
    if(lfd<0)
    {
        perror("socket error!");
        return -1;
    }
    /*Setting up port multiplexing*/
    int opt=1;
    setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(int));
    /*Initialize server-side address structure*/
    struct sockaddr_in  sevr;
    bzero(&sevr,sizeof(sevr));
    sevr.sin_family=AF_INET;
    sevr.sin_port=htons(9090);
    sevr.sin_addr.s_addr=htonl(INADDR_ANY);

    /*Binding socket address structure*/
    int ret=bind(lfd,(sockaddr *)&sevr,sizeof(sockaddr));
    if(ret<0)
    {
        perror("bind error!");
        return -1;
    }
    /*Listening to events*/
    int re= listen(lfd,128);

    /*Create a collection of listened read events*/
    fd_set readfds;
    fd_set tmpfds;

    /*Initialization*/
    FD_ZERO(&readfds);
    FD_ZERO(&tmpfds);
    /*Adding file descriptors to the read event set*/
    FD_SET(lfd,&readfds);
    int maxfd=lfd+1;
    int cfd;
    while(1)
    {
        tmpfds=readfds;
        /*Give the event descriptors in the collection to the kernel to listen */
        /* Listening range, max file descriptors + 1*/
        int nready=select(maxfd+1,&tmpfds,NULL,NULL,NULL);
        cout<<nready<<endl;
        if(nready<0)
        {
            /*Event Terminal*/
            if(errno==EINTR)
                continue;
	    cout<<"select error"<<endl;
            break;
        }

        /*There is a client connection request*/
        if(FD_ISSET(lfd,&tmpfds))
        {
            cfd=accept(lfd,NULL,NULL);
            if(cfd<=0)
            {
                cout<<"accept error"<<endl;
                return -1;
            }
            /*Add cfd to the listener set */
            FD_SET(cfd,&readfds);

            /*Modify the value of maxfds*/
            if(maxfd<=cfd)
            {
                maxfd=cfd;
            }
             /* Only listen events, no read content events*/
            if(--nready==0)
            {
                cout<<"continue"<<endl;
                continue;
            }
        }

        /*Polling to find out the descriptors of read events*/
        for(int i=0;i<=maxfd;i++)
        {
            cout<<i <<endl;
            if(FD_ISSET(i,&tmpfds))
            {
                cout<<"is in cfds"<<endl;
                char buf[1024]={0};
                int n=read(i,buf,sizeof(buf));
                if(n<=0)
                {
                    /*close*/
                    cout<<"read error"<<endl;
                    close(i);
                    /*dele*/
                    FD_CLR(i,&readfds);
                }
                else
                {
                    cout<<buf<<endl;
                    for(int k=0;k<n;k++)
                    {
                        buf[k]=toupper(buf[k]);
                    }
                    write(i,buf,n);
                }

            }
        }
    }

    close(lfd);
    close(cfd);
    return 0;
}