First look at some functions to be used
1. Create a socket ()
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
domain:
Name Purpose Man 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) AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7) AF_AX25 Amateur radio AX.25 protocol AF_ATMPVC Access to raw ATM PVCs AF_APPLETALK AppleTalk ddp(7) AF_PACKET Low level packet interface packet(7) AF_ALG Interface to kernel crypto API
type: 连接类型
SOCK_STREAM Provides sequenced, reliable, two-way, connection- based byte streams. An out-of-band data transmission mechanism may be supported. SOCK_DGRAM Supports datagrams (connectionless, unreliable mes‐ sages of a fixed maximum length). SOCK_SEQPACKET Provides a sequenced, reliable, two-way connection- based data transmission path for datagrams of fixed maximum length; a consumer is required to read an entire packet with each input system call. SOCK_RAW Provides raw network protocol access. SOCK_RDM Provides a reliable datagram layer that does not guar‐ antee ordering. SOCK_PACKET Obsolete and should not be used in new programs; see packet(7).
protocol protocol type
There are three kinds of socket programming, streaming socket (SOCK_STREAM), datagram socket (SOCK_DGRAM), raw socket (SOCK_RAW), the first two are more commonly used. Socket programming based on TCP is a streaming socket.
2. Bind the socket to the address bind ()
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
sockfd is the file descriptor obtained in the last function socket ()
addr structure type pointer to address
struct sockaddr { sa_family_t in_family; char in_data [ 14 ]; }
The length of addrlen is the length of the previous parameter addr, generally obtained by sizeof
struct sockaddr_in { short int sin_family; / * communication type * / unsigned short int sin_port; / * port * / struct in_addr sin_addr; / * Internet address * / unsigned char sin_zero [ 8 ]; / * same length as sockaddr structure * / };
struct in_addr { in_addr_t s_addr; };
3. Listening mode waiting for request linsten ()
int listen(int sockfd, int backlog);
sockfd file descriptor
maximum length of backlog waiting for connection queue
4. Send a connection request to the server connect ()
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
The sockfd file descriptor
addr structure type pointer points to the server address
addrlen structure length
5. The server receives the client's connection accpet ()
int accept(int socket,sockaddr * fromaddr,int * addrlen);
socket file descriptor
fromaddr client address information
addrlen address structure length
6. Send data function send ()
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
sockfd file descriptor
* Data sent by buf
len send data length
flags 0
7. Receive data function recv ()
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
sockfd file descriptor
* buf received data
len received data length
flags 0
8. Close the socket closesocket ()
int closesocket(int socket);
linux:
server:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h> int main () { // Create socket int serv_sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); // Bind socket and IP, port struct sockaddr_in serv_addr; memset ( & serv_addr, 0 , sizeof (serv_addr)); // Each byte is filled with 0 serv_addr.sin_family = AF_INET; // Use IPv4 address serv_addr.sin_addr.s_addr = inet_addr ( " 127.0.0.1 " ); // Specific IP address serv_addr.sin_port = htons ( 1234 ); // Port bind (serv_sock, ( struct sockaddr *) & serv_addr, sizeof (serv_addr)); // Enter the listening state and wait for the user to initiate a request listen (serv_sock, 20 ); // Receive client request struct sockaddr_in clnt_addr; socklen_t clnt_addr_size = sizeof(clnt_addr); int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size); // Send data to the client char str [] = " hello world " ; write(clnt_sock, str, sizeof(str)); // Close the socket close (clnt_sock); close(serv_sock); return 0; }
Client:
#include <stdio.h> #include < string .h> #include <stdlib.h> #include <unistd.h> #include <arpa / inet.h> #include <sys / socket.h> int main () { // Create socket int sock = socket (AF_INET, SOCK_STREAM, 0 ); // Initiate a request to the server (specific IP and port) struct sockaddr_in serv_addr; memset ( & serv_addr, 0 , sizeof (serv_addr)); // Each byte is filled with 0 serv_addr.sin_family = AF_INET; // Use IPv4 address serv_addr.sin_addr.s_addr = inet_addr ( " 127.0.0.1 " ); // Specific IP address serv_addr.sin_port = htons ( 1234 ); // Port connect (sock, ( struct sockaddr *) & serv_addr, sizeof (serv_addr)); // Read the data returned by the server char buffer [ 40 ]; read(sock, buffer, sizeof(buffer)-1); printf("Message form server: %s\n", buffer); // Close the socket close (sock); return 0 ; }
windows:
server:
#include <stdio.h> #include <winsock2.h> #pragma comment (lib, "ws2_32.lib") //加载 ws2_32.dll int main(){ //初始化 DLL WSADATA wsaData; WSAStartup (MAKEWORD ( 2 , 2 ), & wsaData); // Create socket SOCKET servSock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); // Binding socket sockaddr_in sockAddr; memset ( & sockAddr, 0 , sizeof (sockAddr)); // Each byte is filled with 0sockAddr.sin_family = PF_INET; // Use IPv4 address sockAddr.sin_addr.s_addr = inet_addr ( " 127.0.0.1 " ); // Specific IP address sockAddr.sin_port = htons ( 1234 ); // Port bind (servSock, (SOCKADDR *) & sockAddr, sizeof (SOCKADDR)); // Enter listening state listen (servSock, 20 ); // Receive client request SOCKADDR clntAddr; int nSize = sizeof(SOCKADDR); SOCKET clntSock = accept (servSock, (SOCKADDR *) & clntAddr, & nSize); // Send data to the client char * str = " Hello World! " ; send (clntSock, str, strlen (str) + sizeof ( char ), NULL); // Close the socketclosesocket (clntSock); closesocket(servSock); // Terminate the use of DLL WSACleanup (); return 0 ; }
Client:
#include <stdio.h> #include <stdlib.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") //加载 ws2_32.dll int main(){ //初始化DLL WSADATA wsaData; WSAStartup (MAKEWORD ( 2 , 2 ), & wsaData); // Create socket SOCKET sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); // Initiate a request to the server sockaddr_in sockAddr; memset ( & sockAddr, 0 , sizeof (sockAddr)); // Each byte is filled with 0sockAddr.sin_family = PF_INET; sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sockAddr.sin_port = htons(1234); connect (sock, (SOCKADDR *) & sockAddr, sizeof (SOCKADDR)); // Receive the data returned by the server char szBuffer [MAXBYTE] = { 0 }; recv(sock, szBuffer, MAXBYTE, NULL); // Output the received data printf ( " Message form server:% s \ n " , szBuffer); // Close the socket closesocket (sock); // Stop using DLL WSACleanup (); system("pause"); return 0; }