This article belongs to reprint, slightly changes, to facilitate learning.
A Linux Network Programming--Introduction to network knowledge
Linux Network Programming--Introduction to network knowledge
Client and service side
One of the biggest differences between a network program and a normal program is that the network program is made up of two parts-the client and server side.
Client
In a network program, if a program is actively communicating with the outside program, then we refer to this program as a client program. For example, we use an FTP program from another
A place to get the file, it is our FTP program to actively communicate with the outside (get files), so this place our FTP program is the client program.
Service side
The program that corresponds to the client is the service-side program. A program that passively waits for an outside program to communicate with itself is called a service-side program.
For example, the above file acquisition, another place of the program is the server, we get the files from the server.
Mutual customer and service side
In real life some programs are interoperable for both service and client. In this case project, a program is both a client and a server.
Common commands
Because the network program is composed of two parts, so in the debugging time is more troublesome, for this we need to know some common network commands
Netstat
The command netstat is used to display network information such as connections, routing tables, and interface statistics. Netstat has a number of options.
The most common option is-na for displaying detailed network status. For other options we can use the Help manual for detailed information.
Telnet
Telnet is a program used to log in to the remote, but we can use this program to debug our service-side programs.
For example, our server program is listening on port 8888, we can use
telnet localhost 8888
To view the status of the service side.
The Pingping program is used to determine whether the state of the network is normal, and one of the most common uses is
Ping 192.168.0.1
Indicates that we want to see if the hardware connection to 192.168.0.1 is OK
TCP/UDP Introduction
TCP (Transfer Control Protocol) transmission protocol is a connection-oriented protocol, and when our network program uses this protocol,
The network can ensure that our client and server connections are reliable and secure.
The UDP (user Datagram Protocol) User Datagram Protocol is a non-connection-oriented protocol,
This protocol does not guarantee the connection of our network program is reliable, so the program we are writing now generally uses the TCP protocol.
Two Linux Network Programming--Introduction to Elementary network functions (TCP)
A Linux system is programmed by a socket (socket) for network programming. Network programs are called through sockets and several other functions,
Returns a file descriptor for a communication, which we can manipulate as a descriptor for a normal file, which is the benefit of the device-independent nature of Linux.
We can communicate the data between the networks by reading and writing to the descriptor.
(a) socket
int socket (int domain, int type,int protocol)
Domain: Describes the communications Association (AF_UNIX and AF_INET, etc.) used by the host on which our network program resides.
The Af_unix can only be used for single UNIX system interprocess communication,
While Af_inet is for the internet, it can allow remote
Communication between hosts (when we found the domain option in the man socket is pf_* instead of af_*, because GLIBC is a POSIX implementation, instead of AF with PF,
But we can all use the).
Type: The communication protocol used by our network program (Sock_stream,sock_dgram, etc.)
Sock_stream shows that we are using the TCP protocol, which provides sequential, reliable, bidirectional, connection-oriented bit streams.
Sock_dgram indicates that we are using the UDP protocol, which will only provide fixed-length, unreliable, non-connected communication.
Protocol: Because we specify the type, so this place we usually just use the zero to replace the socket for network communication to do the basic preparation.
Returns the file descriptor on success, returns 1 on failure, and looks at errno to know the details of the error.
(ii) BIND
int bind (int sockfd, struct sockaddr *my_addr, int addrlen)
SOCKFD: Is the file descriptor returned by the socket call.
Addrlen: Is the length of the SOCKADDR structure.
MY_ADDR: is a pointer to sockaddr. There is a definition of sockaddr in the
struct sockaddr{
unisgned short as_family;
Char sa_data[14];
};
However, due to the compatibility of the system, we generally do not use this header file, and another structure (struct sockaddr_in) to replace. In the definition of sockaddr_in
struct sockaddr_in{
unsigned short sin_family;
unsigned short int sin_port;
struct IN_ADDR sin_addr;
unsigned char sin_zero[8];
}
We mainly use the internet so
Sin_family is generally af_inet,
The sin_addr set to Inaddr_any indicates that it can communicate with any host.
Sin_port is the port number we want to listen to. Sin_zero[8] is used to populate.
Bind binds the local port to the file descriptor returned by the socket. Success is to return 0, the failure is the same as the socket
(c) Listen
int listen (int sockfd,int backlog)
SOCKFD: Is the file descriptor after bind.
Backlog: Sets the maximum length of the request queue. Use this to indicate the length of the queue that can be described when multiple client programs and server connections are connected.
The Listen function changes the file descriptor of bind to a listening socket. The return condition is the same as bind.
(d) Accept
int accept (int sockfd, struct sockaddr *addr,int *addrlen)
SOCKFD: Is the file descriptor after listen.
Addr,addrlen is used to fill the client's program, the server side as long as the pointer can be passed. Bind,listen and accept are functions used on the server side,
When the accept call is made, the server-side program blocks until a client program makes a connection. When accept succeeds, returns the last server-side file descriptor,
At this point the server can write information to this descriptor. Return on Failure-1
(v) Connect
int connect (int sockfd, struct sockaddr * serv_addr,int addrlen)
The file descriptor returned by the Sockfd:socket.
SERV_ADDR: The server-side connection information is stored. Where Sin_add is the address of the service side
Length of Addrlen:serv_addr
The Connect function is used by the client to connect to the server. On success, return 0,SOCKFD is the file descriptor that communicates with the server, and returns 1 when it fails.
(vi) Examples
/******* Server Program (SERVER.CPP) ************/
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
using namespace Std;
int main (int argc, char *argv[])
{
int sockfd,new_fd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sin_size,portnumber;
Char hello[] = "hello! Fine?\n ";
if (argc! = 2) {
fprintf (stderr, "usage:%s portnumber\a\n", argv[0]);
Exit (1);//force quit
}
if ((Portnumber=atoi (argv[1)) < 0)
{
fprintf (stderr, "usage:%s portnumber\a\n", argv[0]);
Exit (1);
}
/* Start building the socket descriptor on server side */
if ((SOCKFD = socket (af_inet,sock_stream,0)) = =-1)
{
fprintf (stderr, "Socket error:%s\n\a", Strerror (errno));
Exit (1);
}
/* Server-side populated SOCKADDR structure */
Bzero (&server_addr,sizeof (struct sockaddr_in));//#include <string.h> function: The first n bytes of a byte string s are zero.
server_addr.sin_family = af_inet;
SERVER_ADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);
Server_addr.sin_port = htons (portnumber);
/*
*
* HTONL ()--"Host to Network Long"
Ntohl ()--"Network to Host Long"
Htons ()--"Host to Network short"
Ntohs ()--"Network to Host short"
*
*/
Bundle SOCKFD Descriptors
if (bind (SOCKFD, struct sockaddr *) (&SERVER_ADDR), sizeof (struct sockaddr)) = =-1)
{
fprintf (stderr, "Bind err:%s\n\a", Strerror (errno));
Exit (1);
}
/* Listen for SOCKFD descriptors */
if (listen (sockfd,5) = =-1)
{
fprintf (stderr, "Listen error:%s\n\a", Strerror (errno));
Exit (1);
}
while (1) {
The server blocks until the client app builds connection.
sin_size = sizeof (struct sockaddr_in);
if (new_fd = Accept (SOCKFD, (struct sockaddr *) (&CLIENT_ADDR), (socklen_t*) &sin_size)) = =-1)
{
fprintf (stderr, "Accept error:%s\n\a", Strerror (errno));
Exit (1);
}
fprintf (stderr, "Server get connection from%s\n", Inet_ntoa (CLIENT_ADDR.SIN_ADDR));
<arpa/inet.h> network byte order IP conversion dot decimal IP
if (Write (New_fd,hello,strlen (hello)) = =-1)
{
fprintf (stderr, "Write error:%s\n", Strerror (errno));
Exit (1);
}
Close (NEW_FD);
}
Close (SOCKFD);
Exit (0);
}
Client Client.cpp
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
using namespace Std;
int main (int argc,char *argv[])
{
int sockfd;
Char buffer[1024];
struct sockaddr_in server_addr;
struct Hostent *host;
int portnumber,nbytes;
if (argc!=3)
{
fprintf (stderr, "usage:%s hostname portnumber\a\n", argv[0]);
Exit (1);
}
if ((Host=gethostbyname (argv[1))) ==null)
{
fprintf (stderr, "GetHostName error\n");
Exit (1);
}
if ((Portnumber=atoi (argv[2))) <0)
{
fprintf (stderr, "usage:%s hostname portnumber\a\n", argv[0]);
Exit (1);
}
Client program Establishment SOCKFD
if ((Sockfd=socket (af_inet,sock_stream,0)) ==-1)
{
fprintf (stderr, "Socket error:%s\a\n", Strerror (errno));
Exit (1);
}
/* Client program fills the data on the server */
Bzero (&server_addr,sizeof (SERVER_ADDR));
Server_addr.sin_family=af_inet;
Server_addr.sin_port=htons (PortNumber);
server_addr.sin_addr=* (struct in_addr *) host->h_addr);
/* Client Initiates connection request */
if (Connect (SOCKFD, (struct sockaddr *) (&SERVER_ADDR), sizeof (struct sockaddr)) ==-1)
{
fprintf (stderr, "Connect error:%s\a\n", Strerror (errno));
Exit (1);
}
/* Connection succeeded */
if ((Nbytes=read (sockfd,buffer,1024)) ==-1)
{
fprintf (stderr, "Read error:%s\n", Strerror (errno));
Exit (1);
}
buffer[nbytes]= ' + ';
printf ("I have received:%s\n", buffer);
/* End Communication */
Close (SOCKFD);
Exit (0);
}
After GCC compiles these two files, the server and client are generated, and of course, to save things, you can run directly with Codeblocks, and you can see the new build server and client in the directory. Run the./server 8080& (where 8080 is the port number, you can replace it yourself), and then run the./client localhost 8080.
(vii) Summary
In general, the network program is composed of two parts-the client and the server side. The steps to build them are:
Server-side
Socket-->bind-->listen-->accept
Client
Socket-->connect
Linux Network Programming _1