Port ing and UDP Intranet and Internet connection problems

Source: Internet
Author: User
Tags set socket htons

What is port ing:

Port ing (NAT or napt) refers not to a port in the physical sense, but to a port in the TCP/IP protocol. It is a logical port. Port ing: if a computer on the Intranet needs to access the Internet, port ing is required. Port ing is divided into dynamic and static. dynamic port ing: if a computer in the Intranet needs to access xinlang, it will send packets to the NAT gateway, including the IP address, port, and local IP address and port of the Peer (I .e. xinlang, the NAT gateway will replace the local IP address and port with its own public IP address and an unused port, and write down the ing relationship for future packet forwarding. Then, send the data to Sina. Upon receiving the data, Sina responds and sends the data to the unused port of the NAT Gateway. Then, the NAT Gateway forwards the data to the computer on the Intranet, implement communication between the Intranet and the Internet. when the connection is closed, the NAT Gateway releases the port allocated to the connection so that future connections can continue to be used. Dynamic port ing is actually how NAT Gateway works. Static port ing: a fixed port is opened on the NAT gateway, and the data received by the port is set to which IP address and port to forward to the Intranet, whether or not there is a connection, this ing will always exist. You can allow the public network to actively access a computer on the Intranet.

 

UDP Intranet and Internet connection:

For example, if my Intranet IP address is 192.168.0.2 and the port is 3200, I want to communicate with the Internet IP address 220.120.123.42 and the port is 23654 and initiate a request from the client, you can find the server based on the Internet IP address and port. This is a single communication, but it is difficult for the server to send messages to the Intranet machine. If you do not agree, Please carefully consider it before making a brick.

The path of the entire data stream is as follows:

My Intranet IP address and port will change after passing through my gateway. The gateway's Internet may change to 124.253.124.12: 62145. Actually, the address and port after the gateway is converted to the server, that is to say, only the Gateway knows which machine your intranet IP address and port are. Well, it's much easier to think about it. Let's take a look at the code.

For UDP programming, pay attention to the port number of the client. Due to the difference between TCP and UDP, there is no persistent connection or stable communication channel.

# Include <winsock2.h>
# Pragma comment (Lib, "ws2_32 ")

// Socket version

Wsadata;
Word socketversion = makeword (2, 2 );
If (: wsastartup (socketversion, & wsadata )! = 0)
{
Trace (L "init socket DLL error! ");
}

// Clientudp. h

PRIVATE:
DWORD mtargetip; // remote IP address (in the byte sequence of the host)
Word mtargetport; // remote port number
Word mlocalport; // local port number
Bool misprocessing ing; // mark of the data being received
Handle mrcvthread; // handle of the Data receiving thread
Socket msckreceiver; // The socket used for receiving
Socket mscksender; // The socket used for sending
PRIVATE:

// Create/destroy the socket used for sending
Bool createsender (void );
Void deletesender (void );
// Create/destroy the socket used for receiving
Bool createreceiver (void );
Void deletereceiver (void );
Void receivingloop (void); // the process of receiving data.
Static DWORD winapi receivingthrd (void * pparam); // receives the thread execution body
// Start/stop the data receiving thread
Bool startreceiving (void );
Void stopreceiving (void );
Void senddata (char * pchar, long length); // sent data (content, length)
Bool gethostinfo (char * outip, char * outname = NULL); get local information

// Clientudp. cpp

Bool createsender (void)
{
// Deletesender ();

Mscksender = socket (af_inet, sock_dgram, 0 );
If (mscksender! = Invalid_socket)
{
Bool flag = true;
Int RETR = setsockopt (mscksender, sol_socket, so_reuseaddr,
(Char *) & flag, sizeof (FLAG); // set socket to address multiplexing
If (RETR = socket_error)
{
Deletereceiver ();
Return false;
}
Int ret = 0;
Sockaddr_in ADDR;
Memset (char *) & ADDR, 0, sizeof (ADDR ));
Char IP [20];
Char name [20];
Gethostinfo (IP, name); // get the IP address and User Name of the Local Machine
ADDR. sin_addr.s_un.s_addr = inet_addr (IP );
ADDR. sin_family = af_inet;
ADDR. sin_port = htons (clientport); // The local port. Note that the port must be the same as the listening port (which will be written below)
Ret = BIND (mscksender, (struct sockaddr *) & ADDR, sizeof (ADDR); // bind the socket to be sent
If (ret = socket_error)
{
Deletesender ();
Return false;
}

Return true;
}
Return false;
}

// Sent data

Void senddata (char * pchar, long length)
{
Char * TT = new char [Length + 1];
Memset (TT, '/0', Length + 1 );
Memcpy (TT, pchar, length );
Sockaddr_in remote;
Memset (char *) & remote, 0, sizeof (remote ));
Remote. sin_addr.s_un.s_addr = inet_addr (ip_server); // the IP address of the server to be sent.
Remote. sin_family = af_inet;
Remote. sin_port = htons (usrport_server); // server port

Sendto (mscksender, TT, length, 0,
(Sockaddr *) & remote, sizeof (remote ));
Deletesender (); // close the sending socket upon each sending. I tested it. If it is commented out, the server will not receive any feedback from the server next time.
Delete [] tt;
}

Bool gethostinfo (char * outip, char * outname)
{
Char name [300];
If (gethostname (name, 300) = 0)
{
If (outname)
{
Strcpy (outname, name );
}

Phostent hostinfo;
If (hostinfo = gethostbyname (name ))! = NULL)
{
Lpcstr Pip = inet_ntoa (* (struct in_addr *) * hostinfo-> h_addr_list );
Strcpy (outip, pip );
Return true;
}
}
Return false;
}

Void deletesender (void)
{
If (mscksender! = Invalid_socket)
{
Closesocket (mscksender );
Mscksender = invalid_socket;
}
}

// Create the received socket

Bool createreceiver (void)
{
Deletereceiver ();
// Create a socket for UDP Transmission
Msckreceiver = socket (af_inet, sock_dgram, 0 );
If (msckreceiver! = Invalid_socket)
{
// Set the parameter on the socket: Allow address multiplexing
Bool flag = true;
Int ret = setsockopt (msckreceiver, sol_socket, so_reuseaddr,
(Char *) & flag, sizeof (FLAG ));
If (ret = socket_error)
{
Deletereceiver ();
Return false;
}
// Bind the socket to the local port number
Sockaddr_in ADDR;
ADDR. sin_family = af_inet;
ADDR. sin_addr.s_addr = htonl (inaddr_any );
ADDR. sin_port = htons (clientport); // you must set the listening port and sending port to the same port.
Ret = BIND (msckreceiver, (struct sockaddr *) & ADDR, sizeof (ADDR ));
If (ret = socket_error)
{
Deletereceiver ();
Return false;
}
Return true;
}

Return false;
}

// Destroy the receiving socket
Void deletereceiver (void)
{
If (msckreceiver! = Invalid_socket)
{
Closesocket (msckreceiver );
Msckreceiver = invalid_socket;
}
}

// Enable the receiving thread
Bool startreceiving (void)
{
// Create socket if necessary
If (msckreceiver = invalid_socket)
{
Createreceiver ();
}

If (msckreceiver! = Invalid_socket)
{
If (misprocessing ing)
{
Return true;
}

DWORD threadid = 0;
Mrcvthread = createthread (null, 0, receivingthrd,
This, 0, & threadid );
Return (mrcvthread! = NULL );
}
Return false;
}
// Thread function execution body: calls the nested ingloop function of this class.
DWORD winapi cudpclient_onedlg: receivingthrd (void * pparam)
{
Assert (pparam );
Cudpclient_onedlg * pcontroller = (cudpclient_onedlg *) pparam;
Pcontroller-> mongoingloop ();
Return 0;
}
// Data receiving process
Void cudpclient_onedlg: receivingloop (void)
{
Struct sockaddr_in addr_cli;
Int addr_cli_len = sizeof (addr_cli );
Char buffer [max_path] = {'/0 '};
Long bytes = 0;
Misconfiguring = true;
Cstring tnote = l "";
// Wait for receiving data
While (misprocessing ing)
{
Int addr_cli_len = sizeof (addr_cli );
Bytes = recvfrom (msckreceiver, (char *) buffer, max_path, 0, (lpsockaddr) & addr_cli, (int *) & addr_cli_len );
If (Bytes = socket_error | bytes = 0)
{
// If the socket fails to be sent or the socket is disconnected, the loop will jump out.
Misconfiguring = false;
}
Else
{
Cedit * Client1 = (cedit *) This-> getdlgitem (idc_edit1 );
Char * pstr = inet_ntoa (addr_cli.sin_addr );

Ptchar pszop = new tchar [strlen (pstr) * 2 + 1];
Memset (pszop, '/0', strlen (pstr) * 2 + 1 );
Multibytetowidechar (cp_acp, 0, (lpcstr) pstr, (INT) strlen (pstr) * 2, pszop, (INT) strlen (pstr) * 2 );

Ptchar pszcontent = new tchar [bytes * 2 + 1];
Memset (pszcontent, '/0', bytes * 2 + 1 );
Multibytetowidechar (cp_acp, 0, (lpcstr) buffer, bytes * 2, pszcontent, bytes * 2 );

Cstring text1;
Text1.format (L "client 1 IP: % s, Port: % d, reply content: % s", pszop, addr_cli.sin_port, pszcontent );
Tnote + = text1 + L "/R/N ";
Client1-> setwindowtext (tnote );

Delete [] pszop;
Delete [] pszcontent;
Memset (buffer, '/0', strlen (buffer ));

}
}
}
Void cudpclient_onedlg: stopreceiving (void)
{
If (misprocessing ing)
{
Deletereceiver ();
// Make sure the processing ing thread has been terminated
If (mrcvthread! = NULL)
{
Waitforsingleobject (mrcvthread, infinite );
Mrcvthread = NULL;
}
}
}

An example of sending a call is as follows:

{

Createsender ();
Char P [] = "Connect ";
Senddata (p, strlen (p ));

}

// Udpserver. h. The method is basically the same as the client

PRIVATE:
// Create/destroy the socket used for receiving
Bool createreceiver (void );
Void deletereceiver (void );
Void receivingloop (void); // the process of receiving data.
Static DWORD winapi receivingthrd (void * pparam); // receives the thread execution body
// Start/stop the data receiving thread
Bool startreceiving (void );
Void stopreceiving (void );

The key here is

Struct sockaddr_in addr_cli;

Bytes = recvfrom (msckreceiver, (char *) buffer, max_path, 0, (lpsockaddr) & addr_cli, (int *) & addr_cli_len );

After receiving the content from the client, the feedback must be:

Sendto (msckreceiver, (char *) buffer, strlen (buffer), 0, (sockaddr *) & addr_cli, sizeof (addr_cli ));

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/napolun007/archive/2010/12/02/6050241.aspx

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.