当前位置:网站首页>LwIP learning socket (application)
LwIP learning socket (application)
2022-07-03 07:48:00 【Seven demons 71】
Single connection TCP/IP signal communication
Client and server flowchart
Its flow chart is like making a customer service call , The server can be understood as the customer service phone of China Mobile , We are the client .
The server needs to use Socket()
Register a phone , Use bind()
Bind a phone number 10086,listen()
It's a customer service listening to the phone . Then enter accept()
Blocked . After all, at this time, no one calls and there is no need to deal with anything .
At this time, our client can also use socket()
Register a phone , And then use connect()
call 10086.
The customer service, who was originally idle, heard the jingling phone ring , It will start from accept()
The blocking state of jumps out , There will be a famous TCP Three handshake . after “ feed ~” “ feed ?” “ feed ~” after , You can complain about why you gave me a set meal fee barabarabara ……. then 10086 Give his explanation .
Client side usage close()
The function hung up angrily . adopt Four waves after ,10086 Also used close()
Hung up the phone .
The code analysis :
If the basic used in the above flow chart socket API If you don't understand, you can read another article of mine 《Socket API piece 》
Here the code uses wildfire 《LwIP Application development practice guide 》 The routine in .
The server
#include "tcpecho.h"
#include "lwip/opt.h"
#if LWIP_SOCKET
#include <lwip/sockets.h>
#include "lwip/sys.h"
#include "lwip/api.h"
/*--------------------------------------------------------------------*/
#define PORT 5001
#define RECV_DATA (1024)
static void
tcpecho_thread(void *arg)
{
int sock = -1,connected;
char *recv_data;
struct sockaddr_in server_addr,client_addr;
socklen_t sin_size;
int recv_data_len;
recv_data = (char *)pvPortMalloc(RECV_DATA); // apply 1024 Byte memory , As a storage area for receiving data
if (recv_data == NULL)
{
printf("No memory\n"); // If the application fails, jump to __exit
goto __exit;
}
sock = socket(AF_INET, SOCK_STREAM, 0); // Create a socket Socket sock
if (sock < 0)
{
printf("Socket error\n"); // Failed to create, jump to __exit
goto __exit;
}
server_addr.sin_family = AF_INET; // choice IPV4 Protocol family
server_addr.sin_addr.s_addr = INADDR_ANY;// Allow any address links
server_addr.sin_port = htons(PORT); // Set the port number 5001
memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)// Use bind() Information configured before binding
{
printf("Unable to bind\n");
goto __exit;
}
if (listen(sock, 5) == -1)//sock Monitor at most 5 A link
{
printf("Listen error\n");
goto __exit;
}
while (1)
{
sin_size = sizeof(struct sockaddr_in);
connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);// Blocking waiting client Links , If there is no link, the task will enter a blocking state here .
printf("new client connected from (%s, %d)\n",
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));// Print the address and port information of the client
{
int flag = 1;
setsockopt(connected,
IPPROTO_TCP, /* set option at TCP level */
TCP_NODELAY, /* name of option */
(void *) &flag, /* the cast is historical cruft */
sizeof(int)); /* length of option value */
}
while (1)
{
recv_data_len = recv(connected, recv_data, RECV_DATA, 0);
// After the client connects, it will block here , Waiting to receive data
if (recv_data_len <= 0)
// If the client disconnects , The client sends FIN package ,recv() Returns the -1, Get out of this while Loop back to accept() Blocking
break;
printf("recv %d len data\n",recv_data_len);
write(connected,recv_data,recv_data_len);// Writing data
}
if (connected >= 0)
closesocket(connected);// If there was a customer connection before , The client connection will be closed
connected = -1;
}
__exit:
if (sock >= 0) closesocket(sock);// The server socket Create success , Then shut down the server socket
if (recv_data) free(recv_data);// If the memory request is received successfully , Then release the receiving memory
}
void
tcpecho_init(void)
{
sys_thread_new("tcpecho_thread", tcpecho_thread, NULL, 512, 4);
}
client
#include "client.h"
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/api.h"
#include <lwip/sockets.h>
#define PORT 5001
#define IP_ADDR "192.168.0.181"
static void client(void *thread_param)
{
int sock = -1;
struct sockaddr_in client_addr;
uint8_t send_buf[]= "This is a TCP Client test...\n";
while (1)
{
sock = socket(AF_INET, SOCK_STREAM, 0);// Create a client socket It's called sock
if (sock < 0)
{
// If creation fails, delay 10ms Continue to create
printf("Socket error\n");
vTaskDelay(10);
continue;
}
client_addr.sin_family = AF_INET;// Address protocol family set by the server IPV4
client_addr.sin_port = htons(PORT);// The port number set by the server
client_addr.sin_addr.s_addr = inet_addr(IP_ADDR);// The address of the server
memset(&(client_addr.sin_zero), 0, sizeof(client_addr.sin_zero));
if (connect(sock,
(struct sockaddr *)&client_addr,
sizeof(struct sockaddr)) == -1)// Connect to server
{
// If the connection fails, close socket() Time delay 10ms Jump out of while(1)
printf("Connect failed!\n");
closesocket(sock);
vTaskDelay(10);
continue;
}
printf("Connect to iperf server successful!\n");
while (1)
{
if (write(sock,send_buf,sizeof(send_buf)) < 0)// Writing data
break;
vTaskDelay(1000);
}
closesocket(sock);// Close socket
}
}
void
client_init(void)
{
sys_thread_new("client", client, NULL, 512, 4);
}
deficiencies :
The above is provided by wildfire socket The usage of is Duplicate server , Only one connection can be processed at a time . When other clients use connect()
After the connection , If the client does not close()
, Then the server will be blocked in recv() At function . The correct client connection will not be responded by the server .
Solutions :
Use select()
function . stay recv()
Before using select()
First check whether the correct connection arrives .select()
The return value of the function
- When the corresponding set of file descriptors monitored meets the conditions , For example, when there is data in the read file descriptor set , kernel (I/O) Repair according to the state Change file descriptor set , And return a greater than 0 Number of numbers .
- When there is no file descriptor that meets the conditions , And set timeval Monitoring time out ,select The function returns a value of 0 Value .
- When select When a negative value is returned , An error occurred .
Now? FD Add clients to the queue that need to be monitored , Such as keys and com port .
Example reference :
FD_ZERO(&rds);
FD_SET(button_fd,&rds); // Add keys fd
FD_SET(com,&rds)// add to com fd
ret=select(fd+1,&rds,NULL,NULL,NULL);
if(ret<0)
{
printf("select failure\n");
exit(1);
}
if(ret==0)
{
printf("select timeout\n");
}
else if(FD_ISSET(button_fd,&rds)) // Key client connection
{
read(button_fd,&but_status,sizeof(but_status));
}
else if(FD_ISSET(com_fd,&rds)) //com Client connection
{
read(.......);
}
reference :
《LwIP Application development practice guide 》
qicheng777 The blog of
边栏推荐
- Analysis of the problems of the 7th Blue Bridge Cup single chip microcomputer provincial competition
- When did you find out that youth was over
- OSPF protocol summary
- Technical dry goods | some thoughts on the future of AI architecture
- opensips与对方tls sip trunk对接注意事项
- Technical dry goods Shengsi mindspire operator parallel + heterogeneous parallel, enabling 32 card training 242 billion parameter model
- Go language foundation ----- 19 ----- context usage principle, interface, derived context (the multiplexing of select can be better understood here)
- [at] ABC 258g - Triangle triples reachable - violence
- Project experience sharing: Based on mindspore, the acoustic model is realized by using dfcnn and CTC loss function
- Huawei s5700 switch initialization and configuration Telnet, SSH user methods
猜你喜欢
Screenshot tool snipaste
【LeetCode】2. Valid parentheses · valid parentheses
Go language foundation ----- 04 ----- closure, array slice, map, package
[mindspire paper presentation] summary of training skills in AAAI long tail problem
Technical dry goods | alphafold/ rosettafold open source reproduction (2) - alphafold process analysis and training Construction
HarmonyOS第三次培训笔记
An article for you to understand - Manchester code
【MySQL 11】怎么解决MySQL 8.0.18 大小写敏感问题
UA camouflage, get and post in requests carry parameters to obtain JSON format content
Collector in ES (percentile / base)
随机推荐
【LeetCode】2. Valid Parentheses·有效的括号
static关键字
PAT甲级 1027 Colors in Mars
输入三次猜一个数字
EtherCAT state machine transition (ESM)
UA camouflage, get and post in requests carry parameters to obtain JSON format content
【MySQL 13】安装MySQL后第一次修改密码,可以可跳过MySQL密码验证进行登录
Unity XR实现交互(抓取,移动旋转,传送,射击)-Pico
Go language foundation ----- 05 ----- structure
Technical dry goods Shengsi mindspire innovation model EPP mvsnet high-precision and efficient 3D reconstruction
PHP common sorting algorithm
PAT甲级 1029 Median
LwIP learning socket (API)
[MySQL 13] if you change your password for the first time after installing mysql, you can skip MySQL password verification to log in
Precautions for opensips and TLS SIP trunk docking
Pat class a 1031 Hello world for u
Technical dry goods | hundred lines of code to write Bert, Shengsi mindspire ability reward
技术干货 | AlphaFold/ RoseTTAFold开源复现(2)—AlphaFold流程分析和训练构建
Analysis of the problems of the 7th Blue Bridge Cup single chip microcomputer provincial competition
[Development Notes] cloud app control on device based on smart cloud 4G adapter gc211