当前位置:网站首页>Socket communication principle and Practice
Socket communication principle and Practice
2022-07-07 10:30:00 【houxiaoni01】
Course study :socket Introduction to programming
Socket Programming details
Socket Basic preparation for learning network
Linux C Language implementation socket Servers and clients
This article explains in detail Socket Communication principle and practice , In this paper, the example code is introduced in detail . It has a certain reference value for everyone's study or work , Friends in need can refer to .
List of articles
1、TCP/IP、UDP、Socket
Yes TCP/IP、UDP、Socket Programming these words is not new to you ? With the development of network technology , These words fill our ears . So I want to ask :
- What is? TCP/IP、UDP?
- Socket Where is it ?
- Socket What is it? ?
- Can you use them ?
1.1 What is? TCP/IP、UDP?
TCP/IP(Transmission Control Protocol/Internet Protocol) Transmission control protocol / Internet Protocol , It's an industry standard protocol set , It's for the wan (WANs) The design of the .
UDP(User Data Protocol, User datagram protocol ) Is with the TCP The corresponding agreement . It belongs to TCP/IP One of the protocol families .
Here is a picture , Showing the relationship between these agreements .
TCP/IP Protocol family includes transport layer 、 The network layer 、 The link layer . Now you know TCP/IP And UDP It's over .
1.2 Socket Where is it ?
In the figure 1 in , We didn't see it Socket Shadow , So where is it ? Or talk with pictures , Be clear at a glance .
original Socket ad locum .
1.3 Socket What is it? ?
Socket Is the application layer and TCP/IP Intermediate software abstraction layer for protocol family communication , It's a set of interfaces . In design mode ,Socket It's a facade pattern , It's complicated TCP/IP The protocol family is hidden in Socket The back of the interface , For users , A simple set of interfaces is all , Give Way Socket To organize data , To comply with the specified protocol .
1.4 Can you use them ?
Predecessors have done a lot for us , Communication between networks is much simpler , But after all, there is still a lot of work to do . I heard it before Socket Programming , I think it is a relatively advanced programming knowledge , But just find out Socket How programming works , The veil of mystery is lifted .
A scene in life . You have to call a friend , Dial first , A friend picks up the phone when he hears it , That's when you connect with your friends , And you can talk . When the communication is over , Hang up and end the conversation . The scene in life explains how it works , Maybe TCP/IP The agreement clan is born in life , It doesn't have to be .
Start with the server . Initialize the server first Socket, And then bind to the port (bind), Listen to the port (listen), call accept Blocking , Wait for the client to connect . At this time, if there is a client initializing a Socket, And then connect to the server (connect), If the connection is successful , At this time, the connection between the client and the server is established . Client sends data request , The server receives the request and processes it , Then send the response data to the client , Client reads data , Finally, close the connection , An interaction ends .
We understand the value of information exchange , How do processes communicate with each other in the network , For example, we open the browser and browse the web every day when , How does the browser process relate to web Server communication ? When you use QQ When chatting ,QQ How does the process work with the server or where your friends are QQ Process of communication ? It all depends socket? What is socket?socket What are the types of ? also socket The basic function of , These are all what this article wants to introduce .
2、 How processes communicate with each other in the network ?
Local interprocess communication (IPC) There are many ways , But it can be summed up as follows 4 class :
- The messaging ( The Conduit 、FIFO、 Message queue )
- Sync ( The mutex 、 Condition variables, 、 Read-write lock 、 File and write record lock 、 Semaphore )
- Shared memory ( Anonymous and named )
- Remote procedure call (Solaris The door and Sun RPC)
But none of this is the subject of this article ! We are going to talk about how processes in the network communicate with each other ? The first problem to be solved is how to uniquely identify a process , Otherwise, communication is impossible ! It can be done locally through processes PID To uniquely identify a process , But it doesn't work on the Internet . Actually TCP/IP The protocol family has solved this problem for us , Network layer “ip Address ”
Can uniquely identify hosts in the network , and The transport layer “ agreement + port ”
Can uniquely identify applications in the host ( process ). This uses triples (ip Address , agreement , port ) You can identify the process of the network , Process communication in the network can use this flag to interact with other processes .
Use TCP/IP The application program of the protocol usually uses the application programming interface :UNIX BSD Socket (socket) and UNIX System V Of TLI( Has been eliminated ), To achieve communication between network processes . For now , Almost all applications use socket, And now it's the Internet age , Process communication is ubiquitous in the network , That's why I said “ Everything is socket”.
3、 What is? Socket?
We already know that the process in the network is through socket To communicate , What is socket Well ?socket Come of Unix, and Unix/Linux One of the basic philosophies is “ Everything is a document ”, Both can be used. “ open open –> Reading and writing write/read –> close close” Mode to operate . My understanding is that Socket It's an implementation of this pattern ,socket It's a special document , some socket Function is the operation on it ( read / Write IO、 open 、 close ), These functions are described later .
socket The origin of the word
The first use in networking is in 1970 year 2 month 12 The literature published on IETF RFC33 Found in the , The writer is Stephen Carr、Steve Crocker and Vint Cerf. According to the American Museum of computer history ,Croker writes :“ The elements of the namespace can be called socket interfaces . A socket interface forms one end of a connection , And a connection can be completely defined by a pair of socket interfaces .” The Museum of computer history added :“ This is more than BSD The socket interface definition of is about 12 year .”
4、socket Basic operation
since socket yes “open—write/read—close” An implementation of patterns , that socket The function interface corresponding to these operations is provided . Let's say TCP For example , Introduce some basic socket The interface function .
4.1、socket() function
int socket(int domain, int type, int protocol);
socket Function corresponds to the open operation of a normal file . The open operation of a normal file returns a file description word , and socket()
Used to create a socket The descriptor (socket descriptor), It uniquely identifies a socket. This socket Descriptors are the same as document descriptors , Subsequent operations are useful to it , Take it as a parameter , Through it to do some reading and writing operations .
Just as you can give fopen Pass in different parameter values , To open different files . establish socket When , You can also specify different parameters to create different socket The descriptor ,socket The three parameters of the function are :
domain: Protocol domain , Also known as the protocol family (family). Common protocol families are ,
AF_INET
、AF_INET6
、AF_LOCAL
( Or calledAF_UNIX
,Unix Domain socket)、AF_ROUTE
wait . The protocol family decided socket Address type of , The corresponding address must be used in the communication , Such as AF_INET Decided to use ipv4 Address (32 Bit ) And port number (16 Bit ) The combination of 、AF_UNIX Decided to use an absolute pathname as the address .type: Appoint socket type . frequently-used socket Type a ,
SOCK_STREAM
、SOCK_DGRAM
、SOCK_RAW
、SOCK_PACKET
、SOCK_SEQPACKET
wait (socket What are the types of ?).protocol: So it's called Siyi , It's a protocol . Common protocols are ,
IPPROTO_TCP
、IPPTOTO_UDP
、IPPROTO_SCTP
、IPPROTO_TIPC
etc. , They correspond to each other TCP Transfer protocol 、UDP Transfer protocol 、STCP Transfer protocol 、TIPC Transfer protocol ( I'll have a separate discussion on this agreement !).
Be careful : It's not the one above type and protocol Can be combined at will , Such as SOCK_STREAM You can't talk to IPPROTO_UDP Combine . When protocol by 0 when , Will automatically select type Default protocol corresponding to type .
When we call socket
Create a socket when , Back to socket Descriptors exist in the protocol family (address family,AF_XXX) In the space , But there is no specific address . If you want to assign an address to it , You have to call bind()
function , Otherwise, call connect()
、listen()
The system will automatically assign a port at random .
4.2 bind() function
As mentioned above bind() Function to assign a specific address in an address family to socket. For example, it corresponds to AF_INET、AF_INET6 Is to take a ipv4 or ipv6 The combination of address and port number is assigned to socket.
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
The three parameters of the function are :
sockfd: namely socket Description words , It's through socket() Function creates , A unique logo socket.
bind()
The function will bind a name to the description word .addr: One const struct sockaddr * The pointer , Point to bind to sockfd Agreement address for . This address structure is created according to the address socket When the address protocol family is different , Such as :
//ipv4 The corresponding is :
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
};
struct in_addr {
uint32_t s_addr;
};
//ipv6 The corresponding is :
struct sockaddr_in6 {
sa_family_t sin6_family;
in_port_t sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
};
struct in6_addr {
unsigned char s6_addr[16];
};
//Unix The domain corresponds to :
#define UNIX_PATH_MAX 108
struct sockaddr_un {
sa_family_t sun_family;
char sun_path[UNIX_PATH_MAX];
};
- addrlen: It corresponds to the length of the address .
Usually the server will bind a well-known address when it starts ( Such as ip Address + Port number ), Used to provide services , The client can connect to the server through it ; And the client doesn't have to specify , The system automatically assigns a port number and its own ip Address combination . That's why the server is usually on listen We'll call bind()
, And the client will not call , But in connect()
The system randomly generates a .
Network byte order and host byte order
Host byte order
: It's what we usually call the big end and small end mode : Different CPU There are different byte order types , These byte orders refer to the order in which integers are stored in memory , This is called host sequence . Quoting standard Big-Endian and Little-Endian Is defined as follows :
a) Little-Endian That is, the low byte is discharged at the low address end of the memory , The high byte is placed at the high address end of the memory .
b) Big-Endian That is, the high byte is discharged at the low address side of the memory , The low byte is placed at the high address of the memory .Network byte order
:4 Bytes of 32 bit Values are transmitted in the following order :( High byte ------------------->------------------- Low byte ) First of all 0~7bit, secondly 8~15bit, then 16~23bit, And finally 24~31bit. This order of transmission is called big endian . because TCP/IP All binary integers in the header are required to be in this order when they are transmitted in the network , So it's also called network byte order . Byte order , As the name implies, the order of bytes , It is the storage order of data larger than one byte in memory , A byte of data is out of order .therefore
: Binding an address to socket When , Please convert the host byte order to network byte order first , Do not assume that the host byte order is the same as the network byte order Big-Endian. because This problem has led to bloody cases ! Because of this problem in the company project code , It leads to a lot of inexplicable problems , So remember not to make any assumptions about the host byte order , Be sure to convert it into network byte order Assign to socket.
It should be noted that struct in_addr Medium s_addr
It's a kind of uint32_t
Data of type , And in network transmission , Unification is to transmit data in network byte order of large end order , And we are usually used to IP The address format is dotted decimal , for example :“219.228.148.169”, At this time, the following functions will be called for conversion , take IP Address converted to 32 Bit integer data , At the same time, network byte conversion :
in_addr_t inet_addr (const char *__cp) __THROW;
// perhaps
int inet_aton (const char *__cp, struct in_addr *__inp) __THROW; //windows No such function
If we only need to convert network byte order address , You can use the following functions :
/*Functions to convert between host and network byte order. Please note that these functions normally take `unsigned long int' or `unsigned short int' values as arguments and also return them. But this was a short-sighted decision since on different systems the types may have different representations but the values are always the same. */
// h Represents the host byte order
// n Represents network byte order
// s representative short(4 byte )
// l representative long(8 byte )
extern uint32_t ntohl (uint32_t __netlong) __THROW __attribute__ ((__const__));
extern uint16_t ntohs (uint16_t __netshort) __THROW __attribute__ ((__const__));
extern uint32_t htonl (uint32_t __hostlong) __THROW __attribute__ ((__const__));
extern uint16_t htons (uint16_t __hostshort)__THROW __attribute__ ((__const__));
4.3 listen()、connect() function
If as a server , Calling socket()
、bind()
After that, it will call listen()
To monitor this socket, If the client calls connect()
Make a connection request , The server will receive the request .
int listen(int sockfd, int backlog);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
listen The first parameter of the function is the one to listen to socket Description words , The second parameter is the corresponding socket The maximum number of connections that can be queued .socket() Function created socket The default is an active type ,listen Function will socket Become passive , Waiting for customer's connection request .
connect The first parameter of the function is the client's socket Description words , The second parameter is... Of the server socket Address , The third parameter is zero socket The length of the address . The client calls connect Function to establish and TCP Server connection .
4.4 accept() function
TCP The server calls... In turn socket()
、bind()
、listen()
after , Will monitor the designated socket Address .TCP The client calls... In turn socket()
、connect()
After that, I went to TCP The server sent a connection request .TCP After the server listens for the request , Will call accept()
Function to receive the request , So the connection is established . Then we can start the Internet I/O Operation , That is, reading and writing similar to ordinary documents I/O operation .
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept The first parameter of the function is... Of the server socket Description words , The second parameter is pointing to struct sockaddr * The pointer to , Used to return the protocol address of the client , The third parameter is the length of the protocol address . If accpet success , So its return value is a new description word automatically generated by the kernel , Representing and returning customers TCP Connect .
Be careful : accept The first parameter of is the... Of the server socket Description words , It's the server that starts calling socket() Function generated , be called monitor socket Description words
; and accept Function returns Connected socket Description words
. A server usually only creates one listener socket Description words , It exists throughout the life of the server . The kernel creates a connection for each client connection accepted by the server process socket Description words , When the server completes the service to a certain customer , Corresponding connected socket The descriptors are closed .【 monitor socket It's like welcoming guests in a hotel , When the guest is received and handed over to other waiters in the hotel , His work is finished . and accept The new socket generated is the waiter in the hotel , The whole process of subsequent communication is the socket , A waiter like this will always serve guests 】
4.5 read()、write() Such as function
Everything is in place only a strong wind , Now the server has established a connection with the customer . You can call the network I/O Read and write it , That is, the communication between different processes in the network is realized ! The Internet I/O There are several groups of operations :
- read()/write()
- recv()/send()
- readv()/writev()
recvmsg()/sendmsg()
- recvfrom()/sendto()
I recommend using recvmsg()/sendmsg()
function , These two functions are the most common I/O function , You can actually replace all the other functions above with these two functions . Their statements are as follows :
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
#include <sys/types.h>
#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);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
read The function is responsible for from fd Read content in . When the reading is successful ,read Returns the actual number of bytes read , If the value returned is 0 Indicates that the end of the file has been read , Less than 0 Indicates that there is a mistake . If the error is EINTR Explain that reading is caused by interruption , If it is ECONNREST Indicates that there is a problem with the network connection .
write Function will buf Medium nbytes Byte contents written to file descriptor fd. Returns the number of bytes written on success , Return... On failure -1, And set up errno Variable . In a web program , When we write to the socket file descriptor, there are two possibilities .
- 1)write The return value of is greater than 0, Indicates that some or all of the data has been written .
- 2) The value returned is less than 0, There was a mistake . We have to deal with it according to the type of error .
If the error is EINTR Indicates an interrupt error occurred while writing . If EPIPE Indicates that there is a problem with the network connection ( The other party has closed the connection ).
I'm not going to introduce these other pairs one by one I/O Function , Specific see man Document or baidu、Google, The following example will be used to send/recv.
4.6 close() function
After the server has established a connection with the client , I can do some reading and writing , After reading and writing, close the corresponding socket Description words , It's like opening a file after operation fclose Close open files .
#include <unistd.h>
int close(int fd);
close One TCP socket The default behavior is to socket Mark as closed , Then immediately return to the calling process . The descriptor can no longer be used by the calling process , That is to say, we can no longer do read or write The first parameter of .
Be careful :close The operation just makes the corresponding socket Reference count of descriptive words -1, Only if the reference count is 0 When , Will trigger TCP The client sends a termination request to the server .
5、socket in TCP Three handshakes to establish a connection
We know tcp To establish a connection “ Three handshakes ”, That is, three packets are exchanged . The general flow is as follows :
- The client sends a... To the server SYN J
- The server responds to the client with a SYN K, Also on SYN J Confirm ACK J+1
- The client sends a confirmation to the server ACK K+1
Only three handshakes , But this three handshake happened in socket Among the functions of ? Please look at the chart below. :
As you can see from the diagram , When the client calls connect
when , Connection request triggered , Sent... To the server SYN J package , At this time connect Go into blocking mode ; The server listens for connection requests , I will receive SYN J package , call accept
Function to receive the request and send it to the client SYN K ,ACK J+1, At this time accept Go into blocking mode ; Client receives server's SYN K ,ACK J+1 after , At this time connect return , Also on SYN K Confirm ; Server received ACK K+1 when ,accept return , Now the three handshakes are over , Connection is established .
summary : Client's connect On the second return of the three handshakes , On the server side accept On the third return of the three handshakes .
6、socket in TCP Four handshake release connection details
It says socket in TCP The establishment process of three handshakes , And what it involves socket function . Now let's introduce socket The process of releasing a connection with four handshakes in , Please look at the chart below. :
The process is as follows :
- An application process first calls
close
Active close connection , At this time TCP Send a FIN M; - The other end receives FIN M after , Perform passive shutdown , For this FIN Confirm . Its reception is also passed to the application process as a file Terminator , because FIN It means that the application process can no longer receive additional data on the corresponding connection ;
- After a while , Receive the application process call of the end of file
close
Turn it off socket. This leads to its TCP Also send a FIN N; - Received this FIN Source sender of TCP Confirm it .
So there's one in every direction FIN and ACK.
7、 Process and implementation
7.1 TCP
be based on TCP( Connection oriented ) Of socket Programming , It is divided into client side and server side .
The process of the client is as follows :
(1) Create socket (socket)
(2) Send a connection request to the server (connect)
(3) Communicate with the server (send/recv)
(4) Close socket
The process of the server side is as follows :
(1) Create socket (socket)
(2) Bind the socket to a local address and port (bind)
(3) Set the socket to listen mode , Ready to receive client requests (listen)
(4) Waiting for customer requests ; When the request comes , Accept connection request , Returns a new socket corresponding to this connection (accept)
(5) Use the socket returned to communicate with the client (send/recv)
(6) return , Waiting for another customer request .
(7) Close socket .
Server side :
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#define MAXLINE 4096
int main(int argc, char** argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[4096];
int n;
if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
printf("create socket error: %s(errno: %d)/n",strerror(errno),errno);
exit(0);
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(6666);
if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
printf("bind socket error: %s(errno: %d)/n",strerror(errno),errno);
exit(0);
}
if( listen(listenfd, 10) == -1){
printf("listen socket error: %s(errno: %d)/n",strerror(errno),errno);
exit(0);
}
printf("======waiting for client's request======/n");
while(1){
if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){
printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
continue;
}
n = recv(connfd, buff, MAXLINE, 0);
buff[n] = '/0';
printf("recv msg from client: %s/n", buff);
close(connfd);
}
close(listenfd);
}
client :
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#define MAXLINE 4096
int main(int argc, char** argv)
{
int sockfd, n;
char recvline[4096], sendline[4096];
struct sockaddr_in servaddr;
if( argc != 2){
printf("usage: ./client <ipaddress>/n");
exit(0);
}
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("create socket error: %s(errno: %d)/n", strerror(errno),errno);
exit(0);
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(6666);
if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){
printf("inet_pton error for %s/n",argv[1]);
exit(0);
}
if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
printf("connect error: %s(errno: %d)/n",strerror(errno),errno);
exit(0);
}
printf("send msg to server: /n");
fgets(sendline, 4096, stdin);
if( send(sockfd, sendline, strlen(sendline), 0) < 0)
{
printf("send msg error: %s(errno: %d)/n", strerror(errno), errno);
exit(0);
}
close(sockfd);
exit(0);
}
7.2 UDP
UDP The protocol is a connectionless , Unreliable data report (SOCK_DGRAM) Transport services . Use UDP Sockets do not need to establish connections , The server is calling socket() Generate a socket and call bind() After binding the port, you can communicate (recvfrom Functions and sendto function ) 了 ; The client is in use socket() After generating a socket, you can send and receive data to the server address .
Special attention needs to be paid here :TCP Using a stream socket (SOCK_STREAM),UDP Datagram socket is used (SOCK_DGRAM).
Server side :
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<netdb.h>
#include<stdarg.h>
#include<string.h>
#define SERVER_PORT 8000
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
int main()
{
/* establish UDP Socket connector */
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
/* establish socket */
int server_socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(server_socket_fd == -1)
{
perror("Create Socket Failed:");
exit(1);
}
/* Binding socket interface */
if(-1 == (bind(server_socket_fd,(struct sockaddr*)&server_addr,sizeof(server_addr))))
{
perror("Server Bind Failed:");
exit(1);
}
/* The data transfer */
while(1)
{
/* Define an address , Used to capture the client address */
struct sockaddr_in client_addr;
socklen_t client_addr_length = sizeof(client_addr);
/* receive data */
char buffer[BUFFER_SIZE];
bzero(buffer, BUFFER_SIZE);
if(recvfrom(server_socket_fd, buffer, BUFFER_SIZE,0,(struct sockaddr*)&client_addr, &client_addr_length) == -1)
{
perror("Receive Data Failed:");
exit(1);
}
/* from buffer Copy out file_name */
char file_name[FILE_NAME_MAX_SIZE+1];
bzero(file_name,FILE_NAME_MAX_SIZE+1);
strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));
printf("%s", file_name);
}
close(server_socket_fd);
return 0;
}
client :
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<netdb.h>
#include<stdarg.h>
#include<string.h>
#define SERVER_PORT 8000
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
int main()
{
/* Server address */
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(SERVER_PORT);
/* establish socket */
int client_socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(client_socket_fd < 0)
{
perror("Create Socket Failed:");
exit(1);
}
/* Enter the file name into the buffer */
char file_name[FILE_NAME_MAX_SIZE+1];
bzero(file_name, FILE_NAME_MAX_SIZE+1);
printf("Please Input File Name On Server: ");
scanf("%s", file_name);
char buffer[BUFFER_SIZE];
bzero(buffer, BUFFER_SIZE);
strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name));
/* Send filename */
if(sendto(client_socket_fd, buffer, BUFFER_SIZE,0,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0)
{
perror("Send File Name Failed:");
exit(1);
}
close(client_socket_fd);
return 0;
}
7.3 An example of the implementation is given below
First , Let's first give a screenshot of the implementation
The server-side code is as follows :
#include "InitSock.h"
#include <stdio.h>
#include <iostream>
using namespace std;
CInitSock initSock; // initialization Winsock library
int main()
{
// Create a slug
SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// Used to specify the address format used by the socket , Usually use AF_INET
// Specify the type of socket , if SOCK_DGRAM, It uses udp Unreliable transmission
// coordination type Parameters use , Specify the type of protocol to use ( When the socket type is specified , It can be set to 0, Because the default is UDP or TCP)
if(sListen == INVALID_SOCKET)
{
printf("Failed socket() \n");
return 0;
}
// fill sockaddr_in structure , It's a structure
/* struct sockaddr_in { short sin_family; // Address family ( Specify the address format ) , Set to AF_INET u_short sin_port; // Port number struct in_addr sin_addr; //IP Address char sin_zero[8]; // Kongzi Festival , Set to null } */
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(4567); //1024 ~ 49151: Port number registered by ordinary users
sin.sin_addr.S_un.S_addr = INADDR_ANY;
// Bind this socket to a local address
if(::bind(sListen, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("Failed bind() \n");
return 0;
}
// Enter monitor mode
//2 refer to , The maximum number of unprocessed connections allowed to remain in the listening queue
if(::listen(sListen, 2) == SOCKET_ERROR)
{
printf("Failed listen() \n");
return 0;
}
// Loop to accept client's connection request
sockaddr_in remoteAddr;
int nAddrLen = sizeof(remoteAddr);
SOCKET sClient = 0;
char szText[] = " TCP Server Demo! \r\n";
while(sClient==0)
{
// Accept a new connection
//((SOCKADDR*)&remoteAddr) A pointer to a sockaddr_in Pointer to structure , Used to get the other party's address
sClient = ::accept(sListen, (SOCKADDR*)&remoteAddr, &nAddrLen);
if(sClient == INVALID_SOCKET)
{
printf("Failed accept()");
}
printf(" Receiving a connection :%s \r\n", inet_ntoa(remoteAddr.sin_addr));
continue ;
}
while(TRUE)
{
// Send data to client
gets(szText) ;
::send(sClient, szText, strlen(szText), 0);
// Receive data from client
char buff[256] ;
int nRecv = ::recv(sClient, buff, 256, 0);
if(nRecv > 0)
{
buff[nRecv] = '\0';
printf(" Data received :%s\n", buff);
}
}
// Close the connection to the client
::closesocket(sClient);
// Turn off the monitor socket
::closesocket(sListen);
return 0;
}
Client code :
#include "InitSock.h"
#include <stdio.h>
#include <iostream>
using namespace std;
CInitSock initSock; // initialization Winsock library
int main()
{
// Create a slug
SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s == INVALID_SOCKET)
{
printf(" Failed socket() \n");
return 0;
}
// You can also call... Here bind Function to bind a local address
// Otherwise, the system will automatically arrange
// Fill in the remote address information
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(4567);
// Be careful , Here is the server program (TCPServer Program ) Of the machine IP Address
// If your computer is not connected to the Internet , Use it directly 127.0.0.1 that will do
servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if(::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1)
{
printf(" Failed connect() \n");
return 0;
}
char buff[256];
char szText[256] ;
while(TRUE)
{
// Receive data from the server
int nRecv = ::recv(s, buff, 256, 0);
if(nRecv > 0)
{
buff[nRecv] = '\0';
printf(" Data received :%s\n", buff);
}
// Send data to the server
gets(szText) ;
szText[255] = '\0';
::send(s, szText, strlen(szText), 0) ;
}
// Turn off the slug
::closesocket(s);
return 0;
}
Packaged InitSock.h
#include <winsock2.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#pragma comment(lib, "WS2_32") // link to WS2_32.lib
class CInitSock
{
public:
CInitSock(BYTE minorVer = 2, BYTE majorVer = 2)
{
// initialization WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer, majorVer);
if(::WSAStartup(sockVersion, &wsaData) != 0)
{
exit(0);
}
}
~CInitSock()
{
::WSACleanup();
}
};
This is about Socket This is the article on communication principles and practices . I hope it will be helpful for your study , I also hope you can support script house more .
边栏推荐
猜你喜欢
小程序跳转H5,配置业务域名经验教程
ArrayList线程不安全和解决方案
电表远程抄表拉合闸操作命令指令
Using U2 net deep network to realize -- certificate photo generation program
String formatting
[牛客网刷题 Day5] JZ77 按之字形顺序打印二叉树
How to cancel automatic saving of changes in sqlyog database
Leetcode exercise - 113 Path sum II
P2788 数学1(math1)- 加减算式
串口通讯继电器-modbus通信上位机调试软件工具项目开发案例
随机推荐
Elegant controller layer code
【二开】【JeecgBoot】修改分页参数
High number_ Chapter 1 space analytic geometry and vector algebra_ Quantity product of vectors
嵌入式工程师如何提高工作效率
01 use function to approximate cosine function (15 points)
Sword finger offer 38 Arrangement of strings [no description written]
Appx代码签名指南
【华为机试真题详解】高矮个子排队
施努卡:机器视觉定位技术 机器视觉定位原理
基于HPC场景的集群任务调度系统LSF/SGE/Slurm/PBS
Differences between MCU and MPU
PDF文档签名指南
leetcode-304:二维区域和检索 - 矩阵不可变
How embedded engineers improve work efficiency
AHB bus in stm32_ Apb2 bus_ Apb1 bus what are these
OpenGL glLightfv 函数的应用以及光源的相关知识
JMeter loop controller and CSV data file settings are used together
1324:【例6.6】整数区间
Yarn的基础介绍以及job的提交流程
0x0fa23729 (vcruntime140d.dll) (in classes and objects - encapsulation.Exe) exception thrown (resolved)