1. Socket overview
Sockets are intended to be sockets, which are used in networks to describe how different programs in a computer communicate with other computer programs.
There are 3 types of sockets commonly used:
1) Flow socket (Sock--stream): The use of a reliable connection-oriented data communication mode, that is, TCP sockets ;
2) Datagram Socket (Raw Sockets): The use of non-connection-oriented data transmission mode, that is, UDP sockets ;
3) raw sockets (Sock--raw): No processed IP packets can be encapsulated according to the requirements of their own programs.
2. Common functions
1. Create socket function: Returns the file descriptor on success, 1 on Failure
int socket(int domain,inttype,int protocol);//参数domain用于指定创建套接字所使用的协议族(可取AF_UNIX,AF_INET,AF_INTE6)//参数type指定套接字的类型(可取SOCK_STREAM,SOCK_DGRAM,SOCK_RAW)//参数protocol通常设置为0
2. Create a link function on the specified socket: return 0 on success, 1 on Failure
int connect(int sockfd,conststruct sockaddr *serv_addr,socklen_t addrlen);//参数sockfd是一个由函数socket创建的套接字//参数serv_addr是一个地址结构,指定服务器的IP地址和端口号//参数addrlen为参数serv_addr的长度
3. A function that binds a socket to a port: returns 0 on success, 1 on Failure
int bind(int sockfd,struct sockaddr *my_addr,socklen_t addrlen);//一般只有服务器端的程序调用,参数my_addr指定了sockfd将绑定到的本地//地址,可以将参数my_addr的sin_addr设置为INADDR_ANY而不是某个确定//IP地址就可以绑定到任何网络接口。
4. Convert socket to passive listener function: Return 0 on success, 1 on Failure
int listen(int s,int backlog);//参数s为套接字,参数backlog指定链接请求队列的最大长度;
5. Receive connection Request function: Returns the file descriptor on success, 1 on Failure
intaccept(ints*addr*addrlen);//参数s是由函数socket创建,经函数bind绑定到本地某一端口上,然后通过//函数listen转化而来的监听套接字//参数addr用来保存发起连接请求的主机的地址和端口//参数addrlen是addr所指向的结构体的大小
6. Send data function on TCP socket: connected
Contains 3 elements: socket s, outgoing data msg, data length len
ssize_t send(int s,constvoid *msg,size_t len,int flags);//函数只能对处于连接状态的套接字使用,参数s为已建立好连接的套接字描述//符,即accept函数的返回值//参数msg指向存放待发送数据的缓冲区//参数len为待发送数据的长度,参数flags为控制选项,一般设置为0
7. Receive data functions on TCP sockets: Connected
Contains 3 elements: socket s, receive buffer buf, length len
ssize_t recv(int s,void *buf,size_t len,int flags);//函数recv从参数s所指定的套接字描述符(必须是面向连接的套接字)上接收//数据并保存到参数buf所指定的缓冲区//参数len则为缓冲区长度,参数flags为控制选项,一般设置为0
8. Send data function on UCP socket: no connection
ssize_t sendto(int s,constvoid *msg,size_t len,int flags,conststruct sockaddr *to,socklen_t tolen);//函数功能与函数send类似,但函数sendto不需要套接字处于连接状态,所以//该函数通常用来发送UDP数据,同时因为是无连接的套接字,在使用sendto时//需要指定数据的目的地址,参数msg指向待发送数据的缓冲区。//参数len指定了待发送数据的长度//参数flags是控制选项,含义与send函数中的一致//参数to用于指定目的地址,目的地址的长度由tolen指定
9. Receive data functions on UDP sockets: No connection
ssize_t recvfrom(int s ,void *buf,size_t len,int flags,struct sockaddr *from,socklen_t *fromlen);//与函数recv功能类似,只是函数recv只能用于面向连接的套接字,而函数//recvfrom没有此限制,可以用于从无连接的套接字上接收数据//参数buf指向接收缓冲区//参数len指定了缓冲区的大小//参数flags是控制选项,含义与recv中的一致//如果参数from非空,且该套接字不是面向连接的,则函数recvfrom返回时,//参数from中将保存数据的源地址//参数fromlen在调用recvfrom前为参数from的长度,调用recvfrom后将//保存from的实际大小
10. Close Socket Function:
intclose(int fd);//参数fd为一个套接字描述符;
11. Multiplexing Functions:
intselect(int n,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);//参数n是需要监视的文件描述符数//参数readfds指定需要监视的可读文件描述符集合//参数writefds指定需要监视的可写文件描述符集合//参数exceptfds指定需要监视的异常文件描述符的集合//参数timeout指定了阻塞的时间
3. Server-side sockets (socket receiving connection request) creation process
First step: Call the socket function to create the socket.
Step Two: Call the BIND function to assign the IP address and port number.
Part III: Call the Listen function to accept the request state.
Fourth Step: Call the Accept function to accept the connection request.
4. Client socket (socket for sending connection request) creation process
There are only two steps:
1. Call the socket function to create the socket.
2. Call the Connect function to send a connection request to the server side.
5, the Linux file operation
file Descriptor : is an integer that the system automatically assigns to a file or socket.
Whenever a file or socket is generated, the operating system automatically returns an integer to us. This integer is the file descriptor, which is the alias of the created file or socket , which is convenient to call. The file descriptor is also called a handle in Windows.
1. Open File:
2. Close the file or socket:
3. Write data to file:
4. Read the data in the file:
Note: The aliases that are ssize_t = signed int, size_t = unsigned int
taken for the base data type are declared by typedef. Now that you have the basic data type, why do you need to alias it? Because int is generally considered 32-bit, and in the past 16-bit operating systems, int is 16-bit. according to the different system, the change of the Times, the form of the basic data type also changes . If you take an alias for the base data type and later modify it, you only need to modify the TypeDef declaration, which will greatly reduce the code changes.
6. Server-side instance
The server side accepts the connection request program. Compile and run the program to create the server side that waits for the connection request.
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>voidError_handling (Char*message);intMainintargcConst Char* argv[]) {intServ_sock;intClnt_sock;structSockaddr_in serv_addr;structSockaddr_in clnt_addr; Socklen_t clnt_addr_size;CharMessage[] ="Hello world!";if(ARGC! =2) {printf("usage:%s <port>\n", argv[0]);Exit(1); }//(1) Call the socket function to create the socketServ_sock = socket (pf_inet, Sock_stream,0);if(Serv_sock = =-1) Error_handling ("socket () error");memset(&SERV_ADDR,0,sizeof(SERV_ADDR)); serv_addr.sin_family = af_inet; SERV_ADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any); Serv_addr.sin_port = htons (Atoi (argv[1]));//(2) Call the BIND function to assign an IP address and port number if(Bind (Serv_sock, (structsockaddr*) &serv_addr,sizeof(SERV_ADDR)) == -1) Error_handling ("bind () Error");//(3) Call listen function to receive request status if(Listen (Serv_sock,5) == -1) Error_handling ("Listen () Error"); Clnt_addr_size =sizeof(CLNT_ADDR);//(4) Call the Accept function to accept the connection request. The call does not return when there is no connection request, until there is a requestClnt_sock = Accept (Serv_sock, (structsockaddr*) &clnt_addr, &clnt_addr_size);if(Clnt_sock = =-1) Error_handling ("Accept () error");//(5) The Write function is used to transfer data. Execution to this line indicates that a connection request has been made //Transfer data from a message in a client file with a file descriptor of Clnt_sockWrite (clnt_sock, message,sizeof(message)); Close (Clnt_sock);//(6)Close (Serv_sock);//(7) return 0;}voidError_handling (Char*message) {fputs(message, stderr); FPUTC (' \ n ', stderr);Exit(1);}
7. Client instance
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>voidError_handling (Char*message);intMainintargcConst Char* argv[]) {intSockstructSockaddr_in serv_addr;Charmessage[ -];intStr_len;if(ARGC! =3) {printf("Usage:%s <IP> <port>\n", argv[0]);Exit(1); }//(1) Create a socket. But this is not immediately divided into the client or server sideSock = socket (pf_inet, Sock_stream,0);if(Sock = =-1) Error_handling ("socket () error");memset(&SERV_ADDR,0,sizeof(SERV_ADDR)); serv_addr.sin_family = af_inet; SERV_ADDR.SIN_ADDR.S_ADDR = inet_addr (argv[1]); Serv_addr.sin_port = htons (Atoi (argv[2]));//(2) Call the Connect function to send a connection request to the server. This determines the client if(Connect (sock,structsockaddr*) &serv_addr,sizeof(SERV_ADDR)) == -1) Error_handling ("Connect () Error");//(3) Call the Read function to save the data to its own declared message arrayStr_len = Read (sock, message,sizeof(message)-1);if(Str_len = =-1) Error_handling ("read () error");printf("Message from server:%s \ n", message); Close (sock);//(4) return 0;}voidError_handling (Char*message) {fputs(message, stderr); FPUTC (' \ n ', stderr);Exit(1);}
Reference: "TCP/IP network Programming"
Linux network programming and sockets