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)