当前位置:网站首页>I wrote a chat software with timeout connect function
I wrote a chat software with timeout connect function
2022-07-03 23:24:00 【Tao song remains the same】
Hello everyone , I'm brother Tao .
lately , Wrote a simple chat software , Play very smoothly in the LAN , It's about network programming , One scenario is to implement timeout connect function . What does that mean ? Let me give you an example , You'll see .
A boy wants to pursue a girl , But the girl didn't respond , The boy waited silently , Till the end of time . However , The reality is that , Many boys have limited patience , Wait up to three years , It doesn't wait until it expires .
Hand painted by Taoge
The same is true in network programming , By default , establish TCP Connected connect It's blocked , If the other person doesn't respond , Will wait . that , How can I give connect Action setting timeout ?
The train of thought is : hold socket Instead of blocking socket, And then use select Function to monitor socket Related events . I have seen the implementation of many open source network modules , Basically in this way .
Windows Implementation of version
Let's see Windows Implementation of version , The complete code for the client is as follows , Please focus on connect Related code :
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main()
{
// Network initialization
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
WSAStartup( wVersionRequested, &wsaData );
// Create client socket( The default is blocking socket)
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
// Set to non blocking socket
int iMode = 1;
ioctlsocket(sockClient, FIONBIO, (u_long FAR*)&iMode);
// Define the server
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(8888);
// Timeout time
struct timeval tm;
tm.tv_sec = 3;
tm.tv_usec = 0;
int ret = -1;
// Try to connect to the server
if (-1 != connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)))
{
ret = 1; // Successful connection
}
else
{
fd_set set;
FD_ZERO(&set);
FD_SET(sockClient, &set);
if (select(-1, NULL, &set, NULL, &tm) <= 0)
{
ret = -1; // Erroneous (select Error or timeout )
}
else
{
int error = -1;
int optLen = sizeof(int);
getsockopt(sockClient, SOL_SOCKET, SO_ERROR, (char*)&error, &optLen);
if (0 != error)
{
ret = -1; // Erroneous
}
else
{
ret = 1; // No mistake
}
}
}
// Set back to blocking socket
iMode = 0;
ioctlsocket(sockClient, FIONBIO, (u_long FAR*)&iMode); // Set to blocking mode
// connect state
printf("ret is %d\n", ret);
// Send data to the server to test
if(1 == ret)
{
send(sockClient, "hello world", strlen("hello world") + 1, 0);
}
// Release the network connection
closesocket(sockClient);
WSACleanup();
return 0;
}
After testing , When the client connects to the server , If 3 No response in seconds , Then the client will timeout , No longer wait foolishly .
Linux Implementation of version
Next , Let's see Linux Implementation of version , The client code is :
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
#include <time.h>
int main(int argc, char *argv[]) // Note the input parameters , close ip and port
{
int sockClient = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addrSrv;
addrSrv.sin_addr.s_addr = inet_addr(argv[1]);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(atoi(argv[2]));
fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0)|O_NONBLOCK);
int iRet = connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));
printf("connect iRet is %d, errmsg:%s\n", iRet, strerror(errno)); // return -1 Not necessarily abnormal
if (iRet != 0)
{
if(errno != EINPROGRESS)
{
printf("connect error:%s\n", strerror(errno));
}
else
{
struct timeval tm = {3, 0};
fd_set wset, rset;
FD_ZERO(&wset);
FD_ZERO(&rset);
FD_SET(sockClient, &wset);
FD_SET(sockClient, &rset);
int time1 = time(NULL);
int n = select(sockClient + 1, &rset, &wset, NULL, &tm);
int time2 = time(NULL);
printf("time gap is %d\n", time2 - time1);
if(n < 0)
{
printf("select error, n is %d\n", n);
}
else if(n == 0)
{
printf("connect time out\n");
}
else if (n == 1)
{
if(FD_ISSET(sockClient, &wset))
{
printf("connect ok!\n");
fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0) & ~O_NONBLOCK);
}
else
{
printf("unknow error:%s\n", strerror(errno));
}
}
else
{
printf("oh, not care now, n is %d\n", n);
}
}
}
printf("I am here!\n");
getchar();
close(sockClient);
return 0;
}
After testing , When the client connects to the server , If 3 No response in seconds , Then the client will timeout , No longer wait foolishly .
Divergent thinking and interpretation
We noticed that ,Linux The code is more concise , No annoying network initialization and cleanup operation . I love it more Linux.
There is an important problem to pay attention to : stay Windows and Linux in ,select The meaning of the first parameter of the function is different .
stay Windows in , Generally, it is filled in by default -1 Just go ; And in the Linux in , I need to set to fdmax + 1, Why is that ?
see Linux select The meaning of the first parameter : Total number of description sets to be tested , The description set to be tested is from 0,1,2 Start .
If the descriptor you want to detect is 8,9,10, Then the system should actually monitor 0,1,2,3,4,5,6,7 These descriptors .
here , The number of descriptors to be tested is 11, That is to say max(8,9,10) + 1, therefore ,select The first parameter is :fdmax + 1.
Computer network is a subject with strong practicality , When learning computer network and network programming , It is suggested to write more programs 、 Multi debugging 、 Grab more bags , Then compare it with the theory .
I'm familiar with the Internet , Wrote a lot of network programs , I've seen a lot of network open source code , I suggest you go and have a look when you are free Redis Source code , short , awesome .
边栏推荐
- 2022.02.14
- URLEncoder. Encode and urldecoder Decode processing URL
- 2/14 (regular expression, sed streaming editor)
- 2022 Guangdong Provincial Safety Officer a certificate third batch (main person in charge) simulated examination and Guangdong Provincial Safety Officer a certificate third batch (main person in charg
- Ningde times and BYD have refuted rumors one after another. Why does someone always want to harm domestic brands?
- Interesting 10 CMD commands
- FPGA tutorial and Allegro tutorial - link
- Ramble 72 of redis source code
- . Net ADO splicing SQL statement with parameters
- 股票开户最低佣金炒股开户免费,网上开户安全吗
猜你喜欢
QT creator source code learning note 05, how does the menu bar realize plug-in?
Ningde times and BYD have refuted rumors one after another. Why does someone always want to harm domestic brands?
[MySQL] classification of multi table queries
Recursive least square adjustment
Take you to master the formatter of visual studio code
Cgb2201 preparatory class evening self-study and lecture content
Format cluster and start cluster
JDBC Technology
Pyqt5 sensitive word detection tool production, operator's Gospel
How to quickly build high availability of service discovery
随机推荐
Learning notes of raspberry pie 4B - IO communication (SPI)
Sort merge sort
Idea integrates Microsoft TFs plug-in
D24:divisor and multiple (divisor and multiple, translation + solution)
Pyqt5 sensitive word detection tool production, operator's Gospel
Common mode interference of EMC
Go error collection | talk about the difference between the value type and pointer type of the method receiver
Hcip day 15 notes
Mongoose the table associated with the primary key, and automatically bring out the data of another table
[MySQL] sql99 syntax to realize multi table query
[network security] what is emergency response? What indicators should you pay attention to in emergency response?
Scratch uses runner Py run or debug crawler
finalize finalization finally final
How can I get the Commission discount of stock trading account opening? Is it safe to open an account online
Recursive least square adjustment
Maxwell equation and Euler formula - link
2022 a special equipment related management (elevator) examination questions and a special equipment related management (elevator) examination contents
IO flow principle and classification
Qtoolbutton available signal
Alibaba cloud container service differentiation SLO hybrid technology practice