There is a lot of information about TCP IP network traffic, and TCP IP is communicating end-to-end through IP packet mode. A typical TCP packet is as follows
You can see that the packet contains the source port number and the destination port number, when the client socket initiates a connection to the server, the system will randomly assign a source port number to the socket, and we can obtain the original port information of the socket successfully connected via getsocketname. Function prototypes
[CPP]View PlainCopy
- #include <sys/socket.h>
- int getsockname (int sockfd, struct sockaddr *addr, socklen_t *addrlen);
Parameters:
SOCKFD Socket Connection Handle
Addr network address pointer, used to store the local port socket address information,
Addrlen addr size of the space
Returns the result, if the call succeeds, returns 0, and stores the local network address information inside the addr, fails to return 1, and responds with an error message via errno. Source_port.cpp
[CPP]View PlainCopy
- #include <cstring>
- #include <cstdio>
- #include <cstdlib>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <netdb.h>
- #include <errno.h>
- #include <unistd.h>
- #include <arpa/inet.h>
- void Safe_close (int &sock);
- int main (int argc, char *argv[]) {
- int sockfd = 0, n = 0;
- Socklen_t len = 0;
- char host[512] = {0};
- char buf[1024] = {0};
- struct hostent *server;
- struct sockaddr_in serv_addr, loc_addr;
- if (argc < 2) {
- printf ("Please input host name\n");
- Exit (-1);
- }
- strncpy (host, argv[1], sizeof (host));
- Server = gethostbyname (host); //Determine if the domain name entered is correct
- if (NULL = = Server) {
- printf ("Find host:%s failed.\n", host);
- Exit (-1);
- }
- if ( -1 = = (SOCKFD = socket (af_inet, sock_stream, 0)) {//create socket
- memset (buf, 0, sizeof (BUF));
- snprintf (buf, sizeof (BUF), "new socket failed. errno:%d, Error:%s ", errno, Strerror (errno));
- Perror (BUF);
- Exit (-1);
- }
- memset (&serv_addr, 0, sizeof (SERV_ADDR));
- serv_addr.sin_family = af_inet;
- Serv_addr.sin_port = htons (80); //HTTP standard port number
- memcpy (&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
- if ( -1 = = Inet_pton (af_inet, Host, &serv_addr.sin_addr)) {
- memset (buf, 0, sizeof (BUF));
- snprintf (buf, sizeof (BUF), "Inet_pton failed." errno:%d, Error:%s ", errno, Strerror (errno));
- Perror (BUF);
- Exit (-1);
- }
- if ( -1 = = Connect (sockfd, (struct sockaddr *) &serv_addr, sizeof (SERV_ADDR))) {//Connect socket
- memset (buf, 0, sizeof (BUF));
- snprintf (buf, sizeof (BUF), "Connect socket failed. errno:%d, Error:%s ", errno, Strerror (errno));
- Perror (BUF);
- Exit (-1);
- }
- printf ("Connect to%s success.\n", host);
- Len = sizeof (sizeof (LOC_ADDR));
- memset (&loc_addr, 0, Len);
- if ( -1 = = GetSockName (sockfd, (struct sockaddr *) &loc_addr, &len)){//Get local address information for socket bindings /c4>
- memset (buf, 0, sizeof (BUF));
- snprintf (buf, sizeof (BUF), "Get socket name failed. errno:%d, Error:%s ", errno, Strerror (errno));
- Perror (BUF);
- Safe_close (SOCKFD);
- Exit (-1);
- }
- if (loc_addr.sin_family = = af_inet) {//print information
- printf ("Local port:%u\n", Ntohs (Loc_addr.sin_port));
- }
- Safe_close (SOCKFD);
- return 0;
- }
- void Safe_close (int &sock) {
- if ( -1! = sock) {
- Shutdown (sock, Shut_rdwr);
- sock =-1;
- }
- }
This program first initiates a socket connection to a normal HTTP server (BAIDU,QQ,163,CSDN), and when the socket is connected, it obtains the local address of the connection binding via Getsocketname, and obtains the source port number through that address.
Terminal 1: Compiling and running
$ g++ Source_port.cpp
$./a.out www.baidu.com
Connect to www.baidu.com success.
Local port:39702
Terminal 2: Verification via tcpdump capture package
$ sudo tcpdump host Www.baidu.com-v
Tcpdump:listening on eth0, Link-type EN10MB (Ethernet), capture size 65535 bytes
18:38:32.381448 IP (Tos 0x0, TTL-up, id 35033, offset 0, flags [DF], Proto TCP (6), length 60)
icentos.39702 > 220.181.111.188.http:flags [S], cksum 0x8cd2 (Incorrect-0x596a), Seq 2381397554, Win 29200, Opti ONS [MSS 1460,sackok,ts val 3513497323 ECR 0,nop,wscale 7], length 0
18:38:32.425904 IP (Tos 0x0, TTL, id 35033, offset 0, flags [DF], Proto TCP (6), length 60)
220.181.111.188.http > Icentos.39702:flags [S.], cksum 0xc315 (correct), seq 3561856904, Ack 2381397555, win 8192, opt ions [MSS 1424,sackok,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,wscale 5], length 0
18:38:32.425930 IP (Tos 0x0, TTL-up, id 35034, offset 0, flags [DF], Proto TCP (6), length 40)
Comparing terminal One and terminal two indicates that the source port address obtained is correct.
How Linux socket traffic gets the local source port number