C + + Network programming __linux

Source: Internet
Author: User
Tags strcmp htons
Network Programming
1. TCP and UDP comparisons

TCP is connection-oriented, and each interaction process establishes a streaming socket, and the server waits for the client to submit a connection request to it. Once the client request is accepted, a new socket descriptor is returned immediately. This descriptor is used to call the data transfer function and the client to send and receive.

UDP is for connectionless, the two sides set up a datagram socket, the server and the client in the transmission of the data without the need to connect the application and establishment, you can send messages to each other at any time.

Tcp

Advantages: Reliable, stable

Disadvantages: Slow speed, low efficiency, high utilization of system resources, easy to be attacked.

Suitable scenario: Network communication quality requirements high (reliable, stable)

Udp

Advantage: fast, slightly safer than TCP

Disadvantages: unreliable, unstable

Applicable occasions: Network communication quality requirements are not high, fast. 2. Socket Sticky Package Problem

when to think about sticky issues

1: If you use TCP to send data each time, you establish a connection with each other, and then the two sides send out a piece of data, then close the connection, so there will be no sticky problem (because there is only one package structure, similar to the HTTP protocol). Close the connection primarily to both sides send a close connection (refer to the TCP shutdown protocol). Such as: a need to send a string to B, then A and B to establish a connection, and then send both sides of the default good protocol word Furu "Hello give me sth abour yourself", and then B received the message, the buffer data received, and then closed the connection, so the sticky problem does not take into account Because we all know is to send a paragraph of characters;

2: If the sending data has no structure, such as file transmission, so that the sender just send, the receiver only receive storage on OK, also do not consider sticky package;

3: If the two sides establish a connection, need to send a period of time after the connection of different structural data, such as after the connection, there are several structures:

1) "Hellogive me sth abour Yourself"

2) "Don ' tgive me sth abour Yourself"

That way, if the sender sends this two packets continuously, the receiver may be "Hello give me sth abour yourselfdon ' t give me sth abouryourself" so that the receiver will be silly, exactly what to do. Do not know, because the protocol does not prescribe such a strange string, so to deal with it subcontracting, how to divide also need to organize a better package structure, so generally may be in the header plus a data length of the package, to ensure that receive.

Why the Sticky pack appears:

In a convective transmission, UDP does not appear to be sticky because it has message protection boundaries.

1 The sender need wait buffer full before sending out, causing the sticky package

2 receiver does not receive buffer packets in time, causing multiple packets to receive

Solution:

In order to avoid the sticky phenomenon, the following measures can be taken:

One is for the sender caused by the sticky phenomenon, the user can be programmed to avoid, TCP provides the mandatory data transfer immediately operation instructions PUSH,TCP Software received the operation instructions, immediately send this paragraph of data out, without waiting to send buffer full;

Second, for the receiver caused by the sticky package, it can be optimized program design, streamline the process of receiving the workload, improve the priority of receiving process, and so on, so that it received data in time, so as to avoid the phenomenon of sticky packets;

Third, by the receiver control, a packet of data according to the structure of the field, artificial control to receive several times, and then merged, through this means to avoid sticky packets.

The three measures mentioned above have their drawbacks.

The first programming setting method avoids the sticky packets caused by the sender, but it turns off the optimization algorithm, reduces the efficiency of the network transmission, and affects the performance of the application, which is generally not recommended.

The second method can only reduce the likelihood of sticking, but can not completely avoid the sticky packet, when the sending frequency is high, or because the network burst may make a time packet to reach the receiver faster, the receiver is still likely to be too late to receive, resulting in sticky packets.

The third method avoids the sticky package, but the application is less efficient and unsuitable for real-time applications.

A more concise version:

Fixed bag length

Baulinga \ r \ n

The length of the package body of Baotou

Online saying:

One of the most preferred approach is to give a frame of data frame head frame tail, and then the receiver constantly accept and cache the received data, according to the frame end of the frame to separate a complete data, and then separate the fields to get data.

 

If a package is wrong, how to keep recovering.

When sending a message, each message length is specified when it is programmed. If there is a problem with the packet received, we can continue to reply to the original packet by the length of the message. 3. TCP Example

Service side:

#include <stdio.h>

#include <WinSock2.h>

#pragma comment (lib, "Ws2_32.lib")

int _tmain (int argc, _tchar* argv[])

{

Wsadata Wsadata;

int port = 5099;

Char buf[] = "Server: Welcome to login ... \ n";

Load sockets

if (WSAStartup (Makeword (2, 2), &wsadata)!= 0)

{

printf ("Load socket failed:%d......\n", WSAGetLastError ());

return 1;

}

Socket ()

Socket SOCKSRV = socket (af_inet, sock_stream, 0);

Initializing IP and port information

Sockaddr_in addrsrv;

addrsrv.sin_family = af_inet;

Addrsrv.sin_port = htons (port); More than 1024 of the port number

Addrsrv.sin_addr. S_un. S_ADDR = htonl (Inaddr_any);

Bind ()

if (Bind (Socksrv, (lpsockaddr) &addrsrv, sizeof (sockaddr_in)) = = Socket_error)

{

printf ("Socket bind failed:%d......\n", WSAGetLastError ());

return 1;

}

Listen ()

if (listen (socksrv) = = Socket_error) {

printf ("Socket Listener failure:%d......\n", WSAGetLastError ());

return 1;

}

Client Information

Sockaddr_in addrclient;

int len = sizeof (SOCKADDR);

Start listening.

printf ("Server-side startup successful ...") Start listening ... \ n ");

while (1)

{

Waiting for customer requests to arrive

SOCKET Sockconn = Accept (Socksrv, (SOCKADDR *) &addrclient, &len);

if (Sockconn = = Socket_error) {

printf ("Establish Connection failed:%d......\n", WSAGetLastError ());

Break

}

printf ("Establish a connection with the client ...) Ip:[%s]\n ", Inet_ntoa (ADDRCLIENT.SIN_ADDR));

Send data

if (Send (Sockconn, buf, sizeof (BUF), 0) = = socket_error) {

printf ("Send data failed ... \ n");

Break

}

Char recvbuf[100];

memset (recvbuf, 0, sizeof (RECVBUF));

Receive data

Recv (Sockconn, Recvbuf, sizeof (RECVBUF), 0);

printf ("Received data:%s\n", recvbuf);

Closesocket (Sockconn);

}

Close socket

Closesocket (SOCKSRV);

WSACleanup ();

System ("pause");

return 0;

}

Client:

#include <stdio.h>

#include <WinSock2.h>

#pragma comment (lib, "Ws2_32.lib")

int _tmain (int argc, _tchar* argv[])

{

Wsadata Wsadata;

int port = 5099;

Char buff[1024];

memset (buff, 0, sizeof (buff));

Load sockets

if (WSAStartup (Makeword (2, 2), &wsadata)!= 0)

{

printf ("Load socket failed:%d......\n", WSAGetLastError ());

return 1;

}

Initializing IP and port information

Sockaddr_in addrsrv;

addrsrv.sin_family = af_inet;

Addrsrv.sin_port = htons (port);

Addrsrv.sin_addr. S_un. S_ADDR = inet_addr ("127.0.0.1");

Socket ()

Socket sockclient = socket (af_inet, sock_stream, 0);

if (Socket_error = = sockclient) {

printf ("Create Socket failed:%d......\n", WSAGetLastError ());

return 1;

}

Making a connection request to the server

if (Connect (sockclient, (struct sockaddr*) &addrsrv, sizeof (addrsrv)) = = Invalid_socket)

{

printf ("Connect Server failed:%d......\n", WSAGetLastError ());

return 1;

}

Else

{

Receive data

recv (sockclient, buff, sizeof (buff), 0);

printf ("Received data:%s\n", buff);

Send data

Char buf[] = "Client: Request login ...";

Send (Sockclient, buf, sizeof (BUF), 0);

}

Close socket

Closesocket (sockclient);

WSACleanup ();

return 0;

}

Old function Workaround:

4. UDP Example

Service side (receiver):

UDPReceiverTest.cpp: Defines the entry point for a console application.

//

#include "stdafx.h"

#include <stdio.h>

#include <WinSock2.h>

#pragma comment (lib, "Ws2_32.lib")

int _tmain (int argc, _tchar* argv[])

{

Wsadata Wsadata;

int port = 5099;

Load sockets

if (WSAStartup (Makeword (2, 2), &wsadata)!= 0)

{

printf ("Load socket failed:%d......\n", WSAGetLastError ());

return 1;

}

Initializing IP and port information

Sockaddr_in addrsrv;

addrsrv.sin_family = af_inet;

Addrsrv.sin_port = htons (port);

Addrsrv.sin_addr. S_un. S_ADDR = htonl (Inaddr_any);

Socket ()

Socket sockclient = socket (af_inet,sock_dgram, 0);

if (Socket_error = = sockclient) {

printf ("Create Socket failed:%d......\n", WSAGetLastError ());

return 1;

}

Bind ()

if (Bind (Sockclient, (lpsockaddr) &addrsrv, sizeof (sockaddr_in)) = = Socket_error)

{

printf ("Socket bind failed:%d......\n", WSAGetLastError ());

return 1;

}

Sockaddr_in addrclnt;

int nlen = sizeof (SOCKADDR);

News

Char szmsg[1024];

memset (szmsg, 0, sizeof (szmsg));

Waiting for customer requests to arrive

printf ("Server-side startup successful ...") Wait for customer to send data ... \ n ");

while (1)

{

Receive data

if (Socket_error!= recvfrom (sockclient, szmsg, sizeof (szmsg), 0, (sockaddr*) &addrclnt, &nlen))

{

printf ("Sender:%s\n", szmsg);

Char szsrvmsg[] = "Receive ...";

Send data

SendTo (sockclient, szsrvmsg, sizeof (SZSRVMSG), 0, (sockaddr*) &addrclnt, Nlen);

}

}

The following code does not perform the wireless loop above

Close socket

Closesocket (sockclient);

WSACleanup ();

return 0;

}

Client:

UDPSenderTest.cpp: Defines the entry point for a console application.

//

#include "stdafx.h"

#include <stdio.h>

#include <WinSock2.h>

#pragma comment (lib, "Ws2_32.lib")

int _tmain (int argc, _tchar* argv[])

{

Wsadata Wsadata;

int port = 5099;

Load sockets

if (WSAStartup (Makeword (2, 2), &wsadata)!= 0)

{

printf ("Load socket failed:%d......\n", WSAGetLastError ());

return 1;

}

Socket ()

Socket sockclient = socket (af_inet, SOCK_DGRAM, 0);

if (Socket_error = = sockclient) {

printf ("Create Socket failed:%d......\n", WSAGetLastError ());

return 1;

}

Initializing IP and port information

Sockaddr_in addrsrv;

addrsrv.sin_family = af_inet;

Addrsrv.sin_port = htons (port);

Addrsrv.sin_addr. S_un. S_ADDR = inet_addr ("127.0.0.1");

int nlen = sizeof (SOCKADDR);

Send data

Char szmsg[1024];

memset (szmsg, 0, sizeof (szmsg));

SendTo (sockclient, szmsg, sizeof (szmsg), 0, (sockaddr*) &addrsrv, Nlen);

Send data

while (1)

{

Initializing data

Char szmsg[1024];

memset (szmsg, 0, sizeof (szmsg));

printf (enter Q to exit): "Enter the data to be sent."

scanf ("%s", &szmsg);

Exit loop

if (!strcmp (szmsg, "q") | | |!strcmp (szmsg, "Q"))

{

Break

}

Send data

SendTo (sockclient, szmsg, sizeof (szmsg), 0, (sockaddr*) &addrsrv, Nlen);

Empty cache

memset (szmsg, 0, sizeof (szmsg));

//

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.