Socket development, socket

Source: Internet
Author: User

Socket development, socket

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------

Preface-thinking or

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------

The socket has been written a little bit, and it always feels awkward. For example, read, recv, and recvfrom are so amazing. Is this a linux design.

This strong mix of read code, how many people are 'Broken. Think of the <UNIX hate manual> that I 've seen a long time ago, and often write cross-platform

Library. have to think about the design and discover

1) winds has a better understanding of socket design than the linux POSIX design.

2) linux has better performance than winds)

3) the application layer is an incomplete domain. Do not enter a Hutong.

(Note: for some days, winds is particularly annoying and unix-like. However, as you grow up, your understanding has changed a lot and you hate having no money or time)

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------

Text-point proof

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------

1.If yesWrite more cross-platform and thread-safe code

For example, we often use gettimeofday when processing time.

#include <sys/time.h>int gettimeofday(struct timeval * tv, struct timezone * tz);The  functions  gettimeofday() can get and set the time as well as a timezone. The tv argument is a struct timeval (as specified in <sys/time.h>):    struct timeval {        time_t      tv_sec;     /* seconds */        suseconds_t tv_usec;    /* microseconds */    };and gives the number of seconds and microseconds since the Epoch (see time(2)).  The tz argument is a struct timezone:    struct timezone {        int tz_minuteswest;     /* minutes west of Greenwich */        int tz_dsttime;         /* type of DST correction */    };If either tv or tz is NULL, the corresponding structure is not set or returned.  (However, compilation warnings will result if tv is NULL.)The use of the timezone structure is obsolete; the tz argument should normally be specified  as  NULL.

Only the seconds and microseconds of the current time are obtained. A time zone message is provided. This function is not well designed.

If you want your code to run on winds, you may need a portable version.

# Ifdef _ MSC_VER

# Include <winsock2.h> /// gettimeofday-Linux sys/time. in h, a microsecond implementation is obtained. // TV: The returned result contains the number of seconds and the number of microseconds. // tz: The contained time zone. In winds, this variable is not returned. // return: 0 // inline intgettimeofday (struct timeval * TV, void * tz) {struct tm st; SYSTEMTIME wtm; GetLocalTime (& wtm); st. tm_year = wtm. wYear-1900; st. tm_mon = wtm. wMonth-1; // The winds count is better than that of st. tm_mday = wtm. wDay; st. tm_hour = wtm. wHour; st. tm_min = wtm. wMinute; st. tm_sec = wtm. wSecond; st. tm_isdst =-1; // TV-> TV _sec = (long) mktime (& st); // 32-bit strong conversion from data to TV-> TV _usec = wtm. wMilliseconds * 1000; // return 0 in milliseconds;} # endif

Your workload is also getting up. No matter how high or not it is, it is always a bad strategy. Here is a better idea to useTimespec_get

#include <time.h>/* Set TS to calendar time based in time base BASE.  */inttimespec_get (struct timespec *ts, int base){  switch (base)    {    case TIME_UTC:      if (__clock_gettime (CLOCK_REALTIME, ts) < 0)        return 0;      break;    default:      return 0;    }  return base;}

The C11 standard provides time functions for obtaining the second and the second. Both CL and GCC clang provide support. The above is an implementation in glibc. Is it very low.

Point

1.1 code writing should have a strong purpose, and non-special fields should be weakened.

1.2 upper-layer applications should first move closer to the standard, followed by the operating system, and then to the Compiler

The main purpose of CL's implementation of timespec_get should be to support the basic features of C ++ 11 and the implementation of clang.

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------

2.Have you everWSAStartupScold Microsoft SB

Write socket winds will certainly have the following trilogy, or two shards.

// 1. CL compiler set ws2_32.lib to introduce macro _ WINSOCK_DEPRECATED_NO_WARNINGS // 2. Load socket dll WSADATA wsad; WSAStartup (WINSOCK_VERSION, & wsad); // 3. Uninstall WSACleanup

At that time, I thought that linux has such a meaningless operation. In fact, there is a story in it that Microsoft was unable to connect to unix socket at the beginning.

Later, numerous other major packages were upgraded to Winsock, And the dll version was greatly changed. Therefore, the above operation was used to load and bind the dll version to the user layer.

So I really don't need it on linux. I actually need it, but I just helped us do it when I run _ start. So we can do this completely.

Encapsulation

/// Et_init-Method for initiating the socket library in a single instance // inline void socket_init (void) {# ifdef _ MSC_VER WSADATA wsad; WSAStartup (WINSOCK_VERSION, & wsad ); # elif _ GUNC _ signal (SIGPIPE, SIG_IGN) # endif}

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------

3.RememberRead, recv, recvfrom?

Is it still in the fear that everything is dominated by files? implementing this idea is nothing more than registering and switching factory branches. It means that read is a mixture

Body. When we only use socket fd to read data, the final read-> recv function is called, that is, recv (fd, buf, sz, 0). For the latter

ssize_t__libc_recv (int fd, void *buf, size_t len, int flags){#ifdef __ASSUME_RECV_SYSCALL  return SYSCALL_CANCEL (recv, fd, buf, len, flags);#elif defined __ASSUME_RECVFROM_SYSCALL  return SYSCALL_CANCEL (recvfrom, fd, buf, len, flags, NULL, NULL);#else  return SOCKETCALL_CANCEL (recv, fd, buf, len, flags);#endif}

It can be indicated that the Implementation Layer of recv and recvfrom has been entangled, but there is no coupling with the upper layer of read. Therefore, it is best for pure TCP socket.

The practice is to start with recv.

       #include <sys/types.h>       #include <sys/socket.h>       ssize_t recv(int sockfd, void *buf, size_t len, int flags);       ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,                        struct sockaddr *src_addr, socklen_t *addrlen);

The following macros are supported by multiple platforms for recv flags:

#define MSG_OOB         0x1             /* process out-of-band data */#define MSG_PEEK        0x2             /* peek at incoming message */#define MSG_DONTROUTE   0x4             /* send without using routing tables */#if(_WIN32_WINNT >= 0x0502)#define MSG_WAITALL     0x8             /* do not complete until packet is completely filled */#endif //(_WIN32_WINNT >= 0x0502)

In fact, MSG_OOB out-of-band data is meaningless unless it is learned. MSG_PEEK is still used in the previous \ r \ n cut shunting protocol.

Currently, there are basically no scenarios. MSG_WAITALL can be used to replace for read, which was a long time ago. It can slightly improve the performance.

Recv (fd, buf, len, 0) or recv (fd, buf, len, MSG_WAITALL) is used in your frequently-said 'high-performance 'server instead of a hodgedge of read.

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------

4.Is itListen, Accept curious!

First, let's start with a good cp between listen and accept. In fact, the general process is nothing more than listen-> connect-> accept.

First, let's look at the listen section.

/* *    Perform a listen. Basically, we allow the protocol to do anything *    necessary for a listen, and if that works, we mark the socket as *    ready for listening. */SYSCALL_DEFINE2(listen, int, fd, int, backlog){    struct socket *sock;    int err, fput_needed;    int somaxconn;    sock = sockfd_lookup_light(fd, &err, &fput_needed);    if (sock) {        somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;        if ((unsigned int)backlog > somaxconn)            backlog = somaxconn;        err = security_socket_listen(sock, backlog);        if (!err)            err = sock->ops->listen(sock, backlog);        fput_light(sock->file, fput_needed);    }    return err;}

This piece of listen code looks really good. I can see from it that the kernel idea is still registration. There is a maximum value for backlog.

Therefore, it is recommended to write the listen correctly for high-performance servers.

listen(fd, SOMAXCONN)

Submit the size of the listener and connection queue created by listen to the Kernel configuration of the operating system.

For accept, I originally wanted to talk about accept4 + SOCK_NONBLOCK to reduce the socket development process, but I think of unix or winds.

It should not be supported. Still Be Honest With accept + O_NONBLOCK.

SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,        int __user *, upeer_addrlen){    return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);}

Suddenly realized that optimization is the depletion of life, and the pain point is the king.

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------

5.You areSelectHave you ever worried about it? Go to its poll

In fact, it is really amazing to think about the design of the select function. select-> poll-> how many nights have epoll experienced from bed to bed.

Winds and linux have two functions for select, which happen to have the same name.

A real non-blocking connect Client

Usage in select development. Why?Select, because it facilitates winds porting and debugging !!Iocp is very difficult, but it is really difficult to integrate it with epoll

Together. because both of them are quite unexpected. epoll is 61 + 10 points. One iocp is 90-20 points. If it is strong, it requires socket behavior.

Read/write links all need to be extracted. However, with select, you only need to extract the poll listener to trigger the selection. We will have time later.

Detailed analysis of iocp. This section shows you how to perform epoll.

#include <sys/epoll.h>int epoll_create(int size);int epoll_create1(int flags);epoll_create()  creates a new epoll(7) instance.  Since Linux 2.6.8, the size argument is 
ignored, but must be greater than zero; see NOTES below.epoll_create() returns a file descriptor referring to the new epoll instance. This file
descriptor is used for all the subse‐quent calls to the epoll interface. When no longer
required, the file descriptor returned by epoll_create() should be closed by using close(2).
When all file descriptors referring to an epoll instance have been closed, the kernel
destroys the instance and releases the associated resources for reuse.epoll_create1()If flags is 0, then, other than the fact that the obsolete size argument is dropped,
epoll_create1() is the same as epoll_create(). The following value can be included in
flags to obtain different behavior:EPOLL_CLOEXECSet the close-on-exec (FD_CLOEXEC) flag on the new file descriptor. See the description of
the O_CLOEXEC flag in open(2) for reasons why this may be useful.

More specifically

SYSCALL_DEFINE1(epoll_create, int, size){    if (size <= 0)        return -EINVAL;    return sys_epoll_create1(0);}

It can be seen from the above that the recommended epoll_create usage is

epoll_create1(EPOLL_CLOEXEC)

The size is no longer required, and the efd returned by the exec re-startup process can be closed to prevent handle leakage.

The EPOLLIN of epoll is in the

/* Flags for epoll_create1.  */#define EPOLL_CLOEXEC O_CLOEXEC/* Valid opcodes to issue to sys_epoll_ctl() */#define EPOLL_CTL_ADD 1#define EPOLL_CTL_DEL 2#define EPOLL_CTL_MOD 3/* Epoll event masks */#define EPOLLIN     0x00000001#define EPOLLPRI    0x00000002#define EPOLLOUT    0x00000004#define EPOLLERR    0x00000008#define EPOLLHUP    0x00000010/* Set the Edge Triggered behaviour for the target file descriptor */#define EPOLLET (1U << 31)

For general servers, such as game servers, large Web system servers, the advanced select operation is sufficient.

If the code is thrown to the upper-layer. ET mode, the packet exception must be handled at the framework's network layer. However, safe and high-speed channel communication can be attempted.

A set of ET process interaction. epoll features are particularly understandable, registration, listening, and return results. The most disgusting is the operation to return results.

A local code may be displayed.

//// Sp_wait-poll's wait function, waiting for someone else to throw/sp: poll model // e: returned Operation Event Set // max: e maximum length // return: returns the length of the event to be operated. <= 0 indicates failure // int sp_wait (poll_t sp, struct event e [], int max) {struct epoll_event ev [max]; int I, n = epoll_wait (sp, ev, max,-1); for (I = 0; I <n; ++ I) {uint32_t flag = ev [I]. events; e [I]. s = ev [I]. data. ptr; e [I]. write = flag & EPOLLOUT; e [I]. read = flag & (EPOLLIN | EPOLLHUP); e [I]. error = flag & EPOLLERR;} return n ;}

The simplest result is the EPOLLOUT, EPOLLHUP, and EPOLLERR enumeration.

EPOLLHUP solves the problem that listen-> connect-> accept occupies resources and does not release them. In fact, the simplest TCP network is not feasible.

Many requirements (network details, a big project)

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------

6.It's a bit generic. I 'd like to present it at the end of this article.Do not forget your mind

# Include <stdio. h> # include <limits. h> # include <stdint. h> /// obsessive-compulsive disorder × radical cure // file: len. c // make: gcc-g-Wall-O2-o love. out love. c // test: objdump-S love. out // int main (int argc, char * argv []) {const char heoo [] = "Hello World"; for (size_t I = sizeof heoo-1; I <SIZE_MAX; -- I) printf ("% c", heoo [I]); putchar ('\ n'); return 0 ;}

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------

Postscript-strive to go through

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------

Errors are inevitable.

Yesterday reproduce: http://music.163.com/m/song? Id = 3986241 & userid = 16529894

The Carpenters-Yesterday once1_sd,854x480316.mp4: https://pan.baidu.com/s/1slA0yU5

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.