当前位置:网站首页>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 .
边栏推荐
- Simple solution of m3u8 file format
- How to make icons easily
- How can enterprises and developers take advantage of the explosion of cloud native landing?
- What are the securities companies with the lowest Commission for stock account opening? Would you recommend it? Is it safe to open an account on your mobile phone
- 2022 a special equipment related management (elevator) examination questions and a special equipment related management (elevator) examination contents
- Cgb2201 preparatory class evening self-study and lecture content
- QT creator source code learning note 05, how does the menu bar realize plug-in?
- Fashion cloud interview questions series - JS high-frequency handwritten code questions
- Pyqt5 sensitive word detection tool production, operator's Gospel
- ADB related commands
猜你喜欢

Ningde times and BYD have refuted rumors one after another. Why does someone always want to harm domestic brands?

Qtoolbutton available signal

The 2022 global software R & D technology conference was released, and world-class masters such as Turing prize winners attended

Analysis of refrigeration and air conditioning equipment operation in 2022 and examination question bank of refrigeration and air conditioning equipment operation

Common mode interference of EMC

The difference between single power amplifier and dual power amplifier

Selenium check box

C deep anatomy - the concept of keywords and variables # dry inventory #

Format cluster and start cluster

Sort merge sort
随机推荐
[network security] what is emergency response? What indicators should you pay attention to in emergency response?
2022 free examination questions for hoisting machinery command and hoisting machinery command theory examination
In VS_ In 2019, scanf and other functions are used to prompt the error of unsafe functions
Pandaoxi's video
Live app source code, jump to links outside the station or jump to pages inside the platform
Qtoolbutton - menu and popup mode
在恒泰证券开户怎么样?安全吗?
炒股開戶傭金優惠怎麼才能獲得,網上開戶安全嗎
Format cluster and start cluster
Fudan 961 review
How to solve the "safe startup function prevents the operating system from starting" prompt when installing windows10 on parallel desktop?
Yyds dry goods inventory [practical] simply encapsulate JS cycle with FP idea~
D30:color tunnels (color tunnels, translation)
Ningde times and BYD have refuted rumors one after another. Why does someone always want to harm domestic brands?
Enter MySQL in docker container by command under Linux
Pyqt5 sensitive word detection tool production, operator's Gospel
33 restrict the input of qlineedit control (verifier)
Analysis of refrigeration and air conditioning equipment operation in 2022 and examination question bank of refrigeration and air conditioning equipment operation
JDBC Technology
股票开户最低佣金炒股开户免费,网上开户安全吗