C++socket Network Programming (cross-Platform) actual combat HTTP Server (II)

Source: Internet
Author: User

Create a TCP server using the socket


1 First look at TCP

1TCP is connection-oriented and must be three times after the handshake

2TCP provides reliable connection for lost retransmission, RTT estimation physical NIC network cable will affect this packet loss

3TCP sort by managing a sequence number for each segment of the data being sent. No package has a serial number, which is sent to you by the bottom line.

4TCP provides flow control and congestion control: Through window congestion windows can limit traffic, 1000 client TCP can be limited to a multi-block speed to receive your data TCP connection is full-duplex. Not interfering with each other, sending and receiving are simultaneous.

First, we configure the Linux environment is very simple OH

Address is: http://12158490.blog.51cto.com/12148490/1947803

Linux needs to install g++ GCC makefile



1 Start coding on Windows, but our project is in the Linux directory

650) this.width=650; "Src=" https://s3.51cto.com/wyfs02/M00/9B/F3/wKioL1lpfh3hHBReAAAQ6OptOho664.png-wh_500x0-wm_ 3-wmp_4-s_2623743358.png "title=" qov$15~lwb~xnn5hp ' WIU@T.png "alt=" wkiol1lpfh3hhbreaaaq6optoho664.png-wh_50 "/ >


1 initialization

/Initialize the Windows network library, this will load the dynamic library file so we want to load Lib file, can be loaded in VS can also code #pragma comment (lib, "Ws2_32.lib") wsadata ws; WSAStartup (Makeword (2,2), &WS);


2 initialization is done is to create a socket, the socket back to the

is an int type, is the socket established with the customer, the first parameter is used

Protocol is TCP/IP and should be a socket that can also be used for Bluetooth communication protocols

The second parameter is whether TCP or UDP is used here sock_stream is TCP

The third parameter is 0 when the original socket is used.


int sock = socket (af_inet, sock_stream, 0), if (sock = = 1) {printf ("Create err\n"); return-1;} printf ("[%d]", sock);



3 binding

Sockaddr_in is a struct that records ports and IP addresses as well as protocol families.

1 You need to specify a port.

2 bind local IP address, if bind 127.0.0.1 only local access

This network, if bound extranet IP that can only be accessed from outside, cannot be accessed internally

A machine can have two network cards, if you want to be able to access the direct htonl (0), the IP and Du Duan port to bind to which socket,

Bind () if not equal to 0 will fail, and it is easy to fail, it is better to judge.

enum{port=8017} sockaddr_in sa;sa.sin_family = Af_inet;sa.sin_port = Htons (PORT); sa.sin_addr.s_addr = htonl (0); if (bind (sock, (sockaddr*) &sa, sizeof (SA))! = 0) {printf ("Bind Port err\n"); return-2;} printf ("Bind Port OK!!! \ n ");


4 Listening

The binding just makes an identity, and there is no waiting for the customer to connect.

This function starts receiving the user's connection as a call. A second parameter

is the queue length used by the socket, specifying the maximum number of requests that are always allowed in the request queue

Number, meaning that if you receive 10 connections that are not received with accept, you will throw away the new connection.

Listen (socket,10);


4 Getting connected user information

This function is to get access to the user's connection information, and he returns an int that is used to really

And the user to send and receive data, the first parameter created before the sock is to establish a connection with the user, the second parameter is the output of the parameters, that is, you put it in, after the assignment,

Then output, the members of the structure can access the IP and port.

If you do not need an IP address and port, just go directly to the 0.

This is the time to create threads and users to communicate,


sockaddr_in sadd;socklen_t len = sizeof (SADD), int client = accept (sock, (sockaddr*) &sadd, &len); if (Client > 0) {printf ("Client connect ok\n");p rintf ("Sockeid:%d\n", client);//output port number and information char *ip = Inet_ntoa (SADD.SIN_ADDR);// Network byte order to local byte order Oh unsigned short port = Ntohs (sadd.sin_port);p rintf ("IP:%s\n", IP);p rintf ("Port:%d\n", port); Closesocket ( client);}

In general, each connection will be sent to a new thread, and the simple solution is to create a new thread when he comes in. The complex scenario is to create a thread pool, each connecting to a thread, and throwing him to idle threads.



We compile on Linux first punch in this project road strength

650) this.width=650; "Src=" https://s1.51cto.com/wyfs02/M01/9B/F4/wKiom1lphByAcaDzAAAI6F4dDMs617.png-wh_500x0-wm_ 3-wmp_4-s_3093762570.png "title=" Rq{ek]) sxnqvaacetmv0h9s.png "alt=" wkiom1lphbyacadzaaai6f4ddms617.png-wh_50 "/ >

Write a Makefile

650) this.width=650; "Src=" https://s4.51cto.com/wyfs02/M02/9B/F4/wKioL1lphDSikCNcAAAFOp-XjBE140.png-wh_500x0-wm_ 3-wmp_4-s_2277294869.png "title=" Wbs}jsfitc90e]y%_26~x1f.png "alt=" wkiol1lphdsikcncaaafop-xjbe140.png-wh_50 "/ >




Simple makefile

The 4 above are similar to predefined

CC is the compiler

SRC is the source file

OBJ is a compiled file

exec compiles the connection executable file


$ (OBJ) represents a simple point that is similar to using this pre-defined

Start: $ (OBJ)

$ (CC)-O $ (EXEC) $ (OBJ)


It relies on obj and he's going to do it first.

$ (OBJ):

$ (CC)-O $ (OBJ)-C $ (SRC)//compile here only


To delete a compiled file only

Clean

Rm-f $ (OBJ)


Execute executable file

Run

./$ (EXEC)

650) this.width=650; "Src=" https://s1.51cto.com/wyfs02/M00/9B/F4/wKiom1lphEmiAx0wAABCRjOB8XY461.png-wh_500x0-wm_ 3-wmp_4-s_1035654349.png "title=" N (VB) lv9ccuzy]mb) 7Q (rq6.png "alt=" wkiom1lphemiax0waabcrjob8xy461.png-wh_50 "/ >



Start make start

650) this.width=650; "Src=" https://s5.51cto.com/wyfs02/M01/9B/F5/wKiom1lphavQ32lyAABDivf7H78455.png-wh_500x0-wm_ 3-wmp_4-s_315776401.png "title=" c~8gfvm06m%4yo16k$) [hj0.png "alt=" Wkiom1lphavq32lyaabdivf7h78455.png-wh_50 "/>

There will be many errors,

650) this.width=650; "Src=" https://s4.51cto.com/wyfs02/M00/9B/F5/wKiom1lphd2wMjiLAABB9Y4rAnM276.png-wh_500x0-wm_ 3-wmp_4-s_938615570.png "title=" '%3y) 3~701@l~z19d3v5fh3.png "alt=" Wkiom1lphd2wmjilaabb9y4ranm276.png-wh_50 "/>


Reason:

Linux, no library files for Windows, no initialization required

, and some APIs are inconsistent.


Solution:

#ifdef WIN32 What to call if the WIN32 case is


#else is no longer used in the Windows environment


#else


Man socket view Required header file

650) this.width=650; "Src=" https://s3.51cto.com/wyfs02/M00/9B/F4/wKioL1lphnaj5oHvAAAL8OatXSU238.png-wh_500x0-wm_ 3-wmp_4-s_1527445518.png "title=" C ' E5j4kxkjjwrj%1~57~l0a.png "alt=" wkiol1lphnaj5ohvaaal8oatxsu238.png-wh_50 "/ >

It's easy to use.

650) this.width=650; "Src=" https://s2.51cto.com/wyfs02/M01/9B/F5/wKiom1lphqawuhyJAABXbU3EvU0657.png-wh_500x0-wm_ 3-wmp_4-s_3526728051.png "title=" U) pj~1otvs{ymntx$pxas8.png "alt=" wkiom1lphqawuhyjaabxbu3evu0657.png-wh_50 "/ >



In the Red section, fill in what Linux needs, this thing will

It executes at compile time, and he discovers that either windows or #else is executed.

In the code.

650) this.width=650; "Src=" https://s5.51cto.com/wyfs02/M01/9B/F5/wKiom1lphsSw_lkPAAAdyDnuAUM606.png-wh_500x0-wm_ 3-wmp_4-s_819094601.png "title=" mo@~ ' rhovmzss{cxhw_4v ' t.png "alt=" Wkiom1lphssw_lkpaaadydnuaum606.png-wh_50 "/>

The rest is the same. Clossocket Buffering close on the line

Then it can be compiled successfully.


Make start compile to generate a bit

Then make run to execute

650) this.width=650; "Src=" https://s1.51cto.com/wyfs02/M00/9B/F5/wKiom1lph2bx88nRAAA5HspBT0s739.png-wh_500x0-wm_ 3-wmp_4-s_1979248057.png "title=") phodidau9n_98y%6lcj2eg.png "alt=" wkiom1lph2bx88nraaa5hspbt0s739.png-wh_50 "/ >


Start another Linux test, please.

Telnet 192.168.1.125 8013 Test Connection some

And then on the left we see

The IP and port of the connected user are printed.

650) this.width=650; "Src=" https://s2.51cto.com/wyfs02/M00/9B/F4/wKioL1lph6fgsbCVAAGONiicwFY745.png-wh_500x0-wm_ 3-wmp_4-s_152942287.png "title=" ' Xdu} $ILJ ~dq2e (apo]e{g0.png "alt=" Wkiol1lph6fgsbcvaagoniicwfy745.png-wh_50 "/>



The basic process has, after all, only need to follow the compilation of the line.

We start recv receive client send data

The first parameter is the return of the user after you connect to the

The socket Oh, the second parameter is the buffer that stores the data,

The third parameter is the buffer size-1 is to leave the mean put/0 terminator

Fourth 0, it's a system thing.

The return value is the size of the received data

The actual return value will sometimes be greater than 1024 but the sender will

There's some data cut, so it's easy to cause errors

Char Buf[1024];memset (buf, 0, sizeof (BUF)), int len = recv (client, buf, sizeof (BUF)-1, 0);p rint ("recv%s\n", buf);

In Linux compile to execute a bit


Sending data after a send-side connection

650) this.width=650; "Src=" https://s2.51cto.com/wyfs02/M02/9B/F5/wKiom1lpi7DxK6dJAABpq1EDpx8815.png-wh_500x0-wm_ 3-wmp_4-s_763954218.png "title=" f5bprj1brv0uhq_l (j}sqya.png "alt=" Wkiom1lpi7dxk6djaabpq1edpx8815.png-wh_50 "/>


The server received a successful data communication

650) this.width=650; "Src=" https://s4.51cto.com/wyfs02/M02/9B/F5/wKiom1lpi93D8TciAADeoDa2OAE328.png-wh_500x0-wm_ 3-wmp_4-s_546600093.png "title=" Woi$@l$7667fxh$lv8]6]uy.png "alt=" Wkiom1lpi93d8tciaadeoda2oae328.png-wh_50 "/>




Loop receives the user's information, receives it in the dead loop, and exits if the data received <=

If a user sends a "quit" inside, it quits.

for (;;) {memset (buf, 0, sizeof (BUF)), int recv_len = recv (client, buf, sizeof (BUF)-1, 0), if (recv_len <= 0) break;if (strstr (buf , "quit") = NULL) break;printf ("Recv%s\n", buf);}



In Linux compile to execute a bit


Sending data after a send-side connection

650) this.width=650; "Src=" https://s3.51cto.com/wyfs02/M02/9B/F5/wKioL1lpjPOjWlzeAADMPaPMpag632.png-wh_500x0-wm_ 3-wmp_4-s_3584078235.png "title="%0 (_onf~4ni3167_x%j}c3y.png "alt=" wkiol1lpjpojwlzeaadmpapmpag632.png-wh_50 "/ >



Multithreading concurrent processing directly with the C++11 line libraries. No need to consider cross-platform

The problem.

The place to create the thread is the socket that the accept will then return

Give this line Cheng.


#include  <thread>using namespace std;class TcpThread{public:     Thread entry function   Create a     void main ()     {         char buf[1024];      for  (;;)     {memset (buf, 0, sizeof (BUF)); Int recv_len = recv (client,  buf, sizeof (BUF)  - 1, 0);if  (recv_len <= 0) break;if  (Strstr ( buf,  "quit")  != null) {char re[] =  "quit success\n"; int sendlen =  send (Client, re, strlen (re) +1, 0);} Int sendlen = send (client,  "ok\n", 4, 0);p rintf ("recv %s\n",  buf);     }    closesocket (client);             }        //User's Socket    int client = 0;    }; 

How to create threads and get user information accept should be put into a dead loop.

Should be a thread that needs his return value.




Create a thread to consider when to clean up

Several scenarios 1 object Reuse 2 self cleanup



650) this.width=650; "Src=" https://s5.51cto.com/wyfs02/M01/9B/F6/wKiom1lplQbAEFq8AAAt_2cuuJM690.png-wh_500x0-wm_ 3-wmp_4-s_3006341758.png "title=" T}do ([8hm448ck8v7ukqzl6.png "alt=" wkiom1lplqbaefq8aaat_2cuujm690.png-wh_50 "/ >

for  (;;) {//here will block   only wait for a new connection   will execute the following code int client = accept (sock,  (sockaddr*) &sadd,  &len);if  (client > 0) {printf ("client connect ok\n");p rintf ("Sockeid:  %d\n ",  client);//output port number and information Char *ip = inet_ntoa (SADD.SIN_ADDR);//network byte order to local byte order Oh unsigned  short port = ntohs (Sadd.sin_port);p rintf ("ip: %s\n",  ip);p rintf ("port: %d\ n ",  port);} Else{break;} Create a thread    need to consider when to clean up//Several scenarios  1 object multiplexing  2 own cleanup tcpthread *th = new tcpthread (); th->client = client; //get socket//start thread   The first parameter is the address of the entry function (function pointer)//the object called by the second argument std::thread  STH (&tcpthread::main,th);//When the above call is finished   object   will be destroyed/destroyed not affected   but this thread still has some resources not released//  we can directly let him release the call , the main thread does not control the processing of sub-threads, such as suspend   or close//This operation is very dangerous, because the   main thread does not know what stage the child threads are running  //normal situation we do not deal with  detach ()    Releases the resource Sth.detach () of the child thread owned by the main thread;} 


Then porting to Linux makefile requires the addition of STD c++11 to compile successfully

650) this.width=650; "Src=" https://s4.51cto.com/wyfs02/M01/9B/F6/wKioL1lpnAjQh2oiAAAe6pcoS18046.png-wh_500x0-wm_ 3-wmp_4-s_1071493355.png "title=" 0~w~1oi6@xub8239}t68mwy.png "alt=" wkiol1lpnajqh2oiaaae6pcos18046.png-wh_50 "/ >

You also need to add-lpthread

650) this.width=650; "Src=" https://s2.51cto.com/wyfs02/M00/9B/F7/wKiom1lpnbmiMxuLAAAYUTZY-IA850.png-wh_500x0-wm_ 3-wmp_4-s_680741025.png "title=" U0 ' (R[ehncqrais) 0by6wza.png "alt=" Wkiom1lpnbmimxulaaayutzy-ia850.png-wh_50 "/>

There's a problem.

$ (CC) $ (OBJ)-O $ (EXEC)-std=c++11-lthread




This article is from the "12148490" blog, please be sure to keep this source http://12158490.blog.51cto.com/12148490/1947841

C++socket Network Programming (cross-Platform) actual combat HTTP Server (II)

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.