At the beginning of last year, there were a lot of code written in openwrt, although I felt sorry that there was a lot of code written in openwrt in the early days of the company.
Let's briefly introduce the socket multi process server on openwrt.
Look at the code
This is c language code. The code written at that time was not very good. Don't spray it. It should be noted that some Linux libraries are used here. They cannot be compiled directly on Windows. They can be compiled on the subsystem on Windows. If necessary, please see my previous blog.
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h> #include <signal.h> #include <pthread.h> #define IP "192.168.121.1" #define PORT 2050 #define QUEUE 10 #define BUFFER_SIZE 8196 //receive data void *recv_data(int conn_fd); //Get string file parameters char* get_args(); int main() { printf("This is 17:31"); //Manually capture the pipeline rupture signal and ignore it signal(SIGPIPE, SIG_IGN); ///Define sockfd int server_sockfd = socket(AF_INET,SOCK_STREAM, 0); int conn; ///Define sockaddr_in struct sockaddr_in server_sockaddr; server_sockaddr.sin_family = AF_INET;//IPv4 server_sockaddr.sin_port = htons(PORT); server_sockaddr.sin_addr.s_addr = inet_addr(IP);//You need to set the top IP, or you can't connect it bzero(&(server_sockaddr.sin_zero),8);//Fill the rest of the structure ///bind, 0 for success and - 1 for error if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1) { perror("bind"); exit(1); } printf("bind success, start listen!"); ///listen, 0 is returned for success, and - 1 is returned for error if(listen(server_sockfd,QUEUE) == -1) { perror("listen"); exit(1); } while(1) { pthread_t thread; ///Client socket struct sockaddr_in client_addr; socklen_t length = sizeof(client_addr); if (-1 == (conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length))) { perror("accept"); continue; } if (0!= pthread_create(&thread, NULL, recv_data, conn)) { perror("pthread_create"); break; } } shutdown(server_sockfd,2); shutdown(conn,2); return 0; } void *recv_data(int conn_fd) { int recv_len; char recv_buf[BUFFER_SIZE]; for(;;) { bzero(recv_buf, sizeof(recv_buf)); recv_len = recv(conn_fd,recv_buf,BUFFER_SIZE,0); if(-1==recv_len) { perror("recv"); exit(1); } recv_buf[recv_len] = '\0'; if(strncmp(recv_buf,"exit",4)==0) { printf("%s\n",recv_buf); break; } printf("Receive data:%s\n", recv_buf); if(send(conn_fd, get_args(), strlen(get_args()), 0) == -1) { perror("send"); exit(1); } } close(conn_fd); pthread_exit(NULL); } char* get_args() { //char data[8196]; //char *data = malloc(8196); char *data = (char*)calloc(BUFFER_SIZE, sizeof(char));//With initialization char tmp[8] = { 0 }; FILE* pFile = fopen("/etc/config/site-manager", "r"); while ( fread(tmp, sizeof(char), 2, pFile) ) { strcat(data,tmp); bzero(tmp,sizeof(tmp)); //memset(tmp,0,sizeof(tmp)); } fclose(pFile); return data; }
pthread is used here for multithreading. The data is the uci parameter obtained from / etc/config /. You can talk about the uci parameter later. This can be modified from the web page and supports two-way binding.
UDP server is used here, which can also be written as TCP. They are similar and can be studied by ourselves.
int server_sockfd = socket(AF_INET,SOCK_STREAM, 0);
Other notes are very clear. At that time, the attitude of just graduated was still very correct. It is worth noting that there was a problem of pipeline rupture. If the socket client directly hung up the socket connection without the knowledge of the server, it will lead to the connection from the server to the client and the disconnection from the client to the server. At this time, once the server application sends data to the client, There will be an error of pipeline rupture, resulting in the server program being closed. Anyway, let you add the following sentence
//Manually capture the pipeline rupture signal and ignore it signal(SIGPIPE, SIG_IGN);
Write configuration file
Due to the introduction of pthread library, our configuration file needs to be modified.
- Source directory Makefile
argserver : argserver.o $(CC) $(LDFLAGS) argserver.o -o argserver -lpthread argserver.o : argserver.c $(CC) $(CFLAGS) -c argserver.c clean : rm *.o argserver
Here, - lpthread needs to be added during compilation, indicating that the library is added to participate in compilation.
- Outer Makefile
include $(TOPDIR)/rules.mk PKG_NAME:=argserver PKG_RELEASE:=1.0 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) TARGET_LDFLAGS:= -lpthread include $(INCLUDE_DIR)/package.mk define Package/argserver SECTION:=utils CATEGORY:=Utilities TITLE:=argserver -- socket server to get arg info DEPENDS:=+libpthread endef define Package/argserver/description socket server to get arg info . endef define Build/Prepare echo "Here is Package/Prepare" mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ endef define Package/argserver/install echo "Here is Package/install" $(INSTALL_DIR) $(1)/bin $(1)/etc/init.d/ $(INSTALL_BIN) $(PKG_BUILD_DIR)/argserver $(1)/bin/ $(INSTALL_BIN) ./auto/argserver $(1)/etc/init.d/ endef $(eval $(call BuildPackage,argserver))
Note two modifications. The following indicates the addition of dependent libraries. The one above is involved in compilation.
Support pthread
Generally speaking, openwrt should add pthread library by default. If you are not sure, you can find it in the menu
make menuconfig
Use "/" in the menu to search pthread to see if it is checked. If it is checked, our program can run normally. If you can't compile firmware with openwrt, it depends on whether the firmware you use supports pthread. Generally speaking, it does.
test
Just find a udp testing tool on the Internet, like TCPUDPDbg. The next one on the Internet is very simple to use, so I won't write it. I also recommend a multifunctional tool IPOP, which works well. I heard it was developed by Huawei. Just search it.
epilogue
What self starting function depends on my last blog.
end
Perfect flower scattering