Basic Knowledge Section: Http://www.cnblogs.com/Jimmy1988/p/7839940.html
1. Basic process
Process |
Client |
Server |
Comment |
Socket () |
Create socket File Descriptor |
With ← |
Both sides of the communication need to establish Socket file descriptor is the Application layer communication interface |
Bind () |
Options available Typically not bound, automatically assigned by the kernel |
Must-Choose IP address cannot be a public network address remote : Generally set to "0.0.0.0" orINADDR_ANY LAN : Can be set to intranet address |
Detailed Visibility: Https://www.cnblogs.com/ok-lanyan/articles/2634242.html |
Listen () |
Optional, not normally monitored |
Must-Choose To keep the socket in the Listening network state |
Blocking wait |
Connect () |
initiating a link request to the server |
? |
IP and port containing the destination host |
Accept () |
? |
The server accepts the link request After the link is accepted, a new socket descriptor is used, Enable the server to accept multiple links |
You can extract the IP and port of the client |
SEND/RECV () |
Sending and receiving packets |
With ← |
The socket can also be considered a file, can be directly read/write () |
Close () |
Close the socket link |
With ← |
Read/write operation can be closed separately |
2. API1). Socket ()
#include <sys/socket.h>int socket(int domain, int type, int protocol)/* Return Value: * If successed: A file descriptor for new socket * else : -1 */
①. Domain:
The Protocol cluster (address cluster) used to select this communication;
For a detailed definition /usr/include/bits/socket.h
, the commonly used macros are as follows:
Name |
Purpose |
Mans Page |
Af_unix, Af_local |
Local Communication |
UNIX (7) |
Af_inet |
IPV4 Internet Protocols |
IP (7) |
Af_inet6 |
IPV6 Internet Protocols |
IPv6 (7) |
Af_ipx |
Ipx-novell |
Protocols |
Af_netlink |
Kernel User Interface Device |
NetLink (7) |
②. Type
Protocol type
For more information /usr/include/bits/socket_types.h
, see the following:
Type |
Purpose |
Sock_stream |
Provides sequenced, reliable, two-way, connection-based byte streams. An Out-of-band data transmission mechanism is supported. |
Sock_dgram |
Supports Datagrams (Connectionless, Unreliable messages of a fixed maximum length). |
③. Protocol
Typically automatically selected by the system, usually set to 0
2). Bind ()
When socket()
a socket is created, there is a name space, but there is no memory address associated with it;
The purpose of this function is to assign a memory address to the socket
#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)/* Return Value: * If successsed: 0 * else: -1 */
①. socktfd
Socket file descriptor returned by the socket () function
②. Addr
The address space assigned to the socket first address;
According to the agreement, the structure definition is different, can be used to man 7 ip/ipv6/etc..
view;
The general definition form is as follows:
/* Structure describing a generic socket address. */struct sockaddr { __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ char sa_data[14]; /* Address data. */ };/*IF flags = AF_INET, 即IPv4*/struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET */ in_port_t sin_port; /* port in network byte order */ struct in_addr sin_addr; /* internet address */ }; /* Internet address. */ struct in_addr { uint32_t s_addr; /* address in network byte order */ };
③. Addrlen
Address length, usually using sizeof (XX)
3). Listen ()
#include <sys/socket.h>int listen(int sockfd, int backlog)/* * backlog: 请求排队的最大长度 */ /* Return Value * If successed: 0 * else: -1 */
4). Connect ()
#include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);/* Return Value * If successed: 0 * else: -1 */
5). Accept ()
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);/* Return Value * If successed: 有效的接收到的socket描述符 * else: -1 */
6). Read/write ()
When reading and writing, the socket can be regarded as a normal file, so read and write the same way as ordinary files:
#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);ssize_t write(int fd, const void *buf, size_t count);
7). SEND/RECV ()
Read and write operations for connection-oriented sockets
#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);ssize_t recv(int sockfd, void *buf, size_t len, int flags);/* Arguments:
Flags
enum {Msg_oob = 0x01,/* Process Out-of-band data. */#define MSG_OOB Msg_oob Msg_peek = 0x02,/* PEEK at incoming messages. */#define Msg_peek Msg_peek Msg_dontroute = 0x04,/* Don ' t use local routing. */#define Msg_dontroute msg_dontroute#ifdef __USE_GNU/* DECnet uses a different name. */Msg_tryhard = msg_dontroute,# define Msg_tryhard msg_dontroute#endif Msg_ctrunc = 0x08,/* Control da Ta lost before delivery. */#define MSG_CTRUNC Msg_ctrunc msg_proxy = 0x10,/* supply or ask second address. */#define MSG_PROXY Msg_proxy msg_trunc = 0x20, #define MSG_TRUNC msg_trunc msg_dontwait = 0x40,/* nonb Locking IO. */#define MSG_DONTWAIT msg_dontwait Msg_eor = 0x80,/* End of record. */#define MSG_EOR Msg_eor Msg_waitall = 0x100,/* Wait for a full request. */#define Msg_waitall Msg_waitall Msg_fin = 0x200, #define Msg_fin msg_fin Msg_syn = 0x400, #define Msg_sy N Msg_syn msg_confirm = 0x800,/* CONFIRM path validity. */#define MSG_CONFIRM msg_confirm Msg_rst = 0x1000, #define Msg_rst msg_rst msg_errqueue = 0x2000,/* fetc H Message from error queue. */#define MSG_ERRQUEUE Msg_errqueue msg_nosignal = 0x4000,/* do not generate sigpipe. */#define Msg_nosignal msg_nosignal Msg_more = 0x8000,/* Sender would send more. */#define Msg_more Msg_more Msg_waitforone = 0x10000,/* Wait for at least one packet to return.*/#define MSG_WAITF Orone Msg_waitforone msg_cmsg_cloexec = 0x40000000/* Set close_on_exit for file Descripto R received through Scm_rights. */#define MSG_CMSG_CLOEXEC msg_cmsg_cloexec};
8). Close/shutdown ()
Two ways to close the socket
I. Close ()
Completely close the socket channel, including read and write
#include <unistd.h>int close(int fd);
II. Shutdown ()
Enhanced flexibility to selectively turn off read or write
#include <sys/socket.h>int shutdown(int sockfd, int how);
How:
- How=0: Only the read channel is closed;
- How=1: Only write channels are closed
- how=2: Closing the read-write channel
9). Getsockname/getpeername () I. Get the local address of the socket
Requirements: Completed binding to IP
II. Get socket Remote Information
Requirement: The socket has been connected remotely
10). Get information such as native IP address
#include <ifaddrs.h>int getifaddrs(struct ifaddrs **ifap);void freeifaddrs(struct ifaddrs *ifa)/*Return value: * If successed:0 * else: -1 */ struct ifaddrs { struct ifaddrs *ifa_next; /* Next item in list */ char *ifa_name; /* Name of interface */ unsigned int ifa_flags; /* Flags from SIOCGIFFLAGS */ struct sockaddr *ifa_addr; /* Address of interface */ struct sockaddr *ifa_netmask; /* Netmask of interface */ union { struct sockaddr *ifu_broadaddr; /* Broadcast address of interface */ struct sockaddr *ifu_dstaddr; /* Point-to-point destination address */ } ifa_ifu; #define ifa_broadaddr ifa_ifu.ifu_broadaddr #define ifa_dstaddr ifa_ifu.ifu_dstaddr void *ifa_data; /* Address-specific data */ };
3. Sample Code
This implementation of Client/server on both ends of the real-time chat function, do not affect each other, can send/receive data at any time;
When you enter "quit", the link ends.
1. client.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include < pthread.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include < netinet/ip.h> #include <errno.h> #define SIZE 1024#define PORT 12345//#define IP_ADDR "192.168.139.129" #define Ip_addr "139.196.121.132"//#define IP_ADDR "47.89.246.154" int sockfd;void *snd (void) {int len = 0; Char Buf[size]; while (1) {memset (buf, ' n ', sizeof (BUF)); printf ("\ninput msg Send to Server:"); Fgets (buf, SIZE, stdin); if (buf[0]! = ' + ') {len = Send (SOCKFD, buf, sizeof (BUF), 0); if (Len < 0) {printf ("Snd:some Error occured or disconnection!\n"); Break } if (!strncasecmp (buf, "Quit", 4)) {printf ("Snd:sub thread has Qu It!\n "); Break } printf ("\nsend msg:%s \ n", buf); }} pthread_exit (NULL);} void *rcv (void) {int len=0; Char Buf[size]; while (1) {memset (buf, ' n ', sizeof (BUF)); Len = recv (SOCKFD, buf, SIZE, 0); if (Len < 0) {printf ("Rcv:some error occured!\n"); Break } if (!strncasecmp (buf, "Quit", 4)) {printf ("Rcv:sub thread has quit!\n"); Break } printf ("\nthe received msg:%s\n", buf); } pthread_exit (NULL);} int main (int argc, char *argv[]) {int ret; 1. Create Socket SOCKFD = socket (af_inet, sock_stream, 0); if ( -1 = = sockfd) {perror ("socket"); Exit (Exit_failure); }//2. Bind the IP addr struct sockaddr_in dest_addr; memset (&dest_addr, 0, sizeof (struct sockaddr_in)); dest_addr.sin_family = af_inet; Dest_addr.sin_port = htons (port); DEST_ADDR.SIN_ADDR.S_ADDR = inet_addr (IP_ADDR);/* ret = BinD (SOCKFD, (struct sockaddr *) &dest_addr, sizeof (struct sockaddr_in)); if ( -1 = = ret) {perror ("bind"); Exit (Exit_failure); } *///3. Request the connection ret = connect (SOCKFD, (struct sockaddr *) &dest_addr, sizeof (DEST_ADDR)); if ( -1 = = ret) {perror ("connect"); Exit (Exit_failure); } printf ("Connect the server (ip:%s) successed!\n", ip_addr); 5. Send/receive the message pthread_t tid1, Tid2; if (0! = pthread_create (&TID1, NULL, (void *) *snd, null)) {perror ("pthread_create"); Exit (errno); } if (0! = pthread_create (&tid2, NULL, (void *) *RCV, null)) {perror ("pthread_create"); Exit (errno); } pthread_join (Tid1, NULL); Pthread_join (Tid2, NULL); return 0;}
2. Server.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include < pthread.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include < netinet/ip.h> #define SIZE 1024#define PORT 12345//#define IP_ADDR "192.168.139.129" #define IP_ADDR "139.196.121.132 "Int main (int argc, char *argv[]) {int ret; pthread_t Tid; int sockfd; 1. Create Socket SOCKFD = socket (af_inet, sock_stream, 0); if ( -1 = = sockfd) {perror ("socket"); Exit (Exit_failure); }//2. Bind the IP addr struct sockaddr_in local_addr; memset (&local_addr, 0, sizeof (struct sockaddr_in)); local_addr.sin_family = af_inet; Local_addr.sin_port = htons (port); LOCAL_ADDR.SIN_ADDR.S_ADDR = inet_addr (IP_ADDR); ret = bind (SOCKFD, (struct sockaddr *) &local_addr, sizeof (struct sockaddr_in)); if ( -1 = = ret) {perror ("bind"); Exit (Exit_failure); }//3. Listen the connection unsigned int lisnum = 5; RET = Listen (SOCKFD, lisnum); if ( -1 = = ret) {perror ("listen"); Exit (Exit_failure); } printf ("Wait for Client connection!\n"); 4. Accept the connection int new_fd; Socklen_t Len; struct sockaddr_in client_addr; NEW_FD = Accept (SOCKFD, (struct sockaddr *) &client_addr, &len); if ( -1 = = new_fd) {perror ("accept"); Exit (Exit_failure); } else {//printf ("Server Got Connection: \n\taddress:%s\tport:%d\tsocket=%d\n", Inet_ntoa (client_addr.si N_ADDR), Ntohs (Client_addr.sin_port), NEW_FD); }//5. Send/receive the message char buf[size]; ssize_t length; pid_t pid; PID = fork (); if (PID = =-1) {perror ("fork"); Exit (Exit_failure); } if (pid = = 0) {while (1) {memset (buf, ' n ', SIZE); printf ("Pls input the MSG to send:"); Fgets (buf, SIZE, stdin); if ((Length=strlen (BUF)) < 0) {printf ("Send error, the length=%d\n", Lengt h); Break } length = Send (NEW_FD, buf, sizeof (BUF), 0); if (!strncasecmp (buf, "Quit", 4)) {printf ("Snd:close the connection!\n"); Break }}} else {while (1) {memset (buf, ' n ', SIZE); Length = recv (NEW_FD, buf, SIZE, 0); if (length >= 0) {printf ("\nreceive msg:%s\n", buf); } else {printf ("Error occured\n"); Break } if (!strncasecmp (buf, "Quit", 4)) {printf ("Recv:close the connection!\n"); Break }}}//close the socket Close (SOCKFD); Close (NEW_FD); return 0;}
Socket Programming-API