TCP/IP Communication Using Socket Programming

TCP/IP Communication Using Socket Programming

OSI Reference Model

OSI (Open System Interconnect) is the Open Systems Interconnection model. It is commonly referred to as the OSI reference model, which was researched by the ISO (International Organization for Standardization) in 1985 for network interconnection.

To better promote network applications, the ISO introduced the OSI reference model. Its meaning is to recommend that all companies use this standard to control networks. This way, all companies have the same standards, enabling interconnection.

OSI defines a seven-layer framework for network interconnection (Physical Layer, Data Link Layer, Network Layer, Transport Layer, Session Layer, Presentation Layer, Application Layer), which is the ISO Open Systems Interconnection Reference Model. As shown in the figure below.

Each layer implements its own functions and protocols and completes interface communication with adjacent layers. The services defined by OSI detail what services each layer provides. The service of a certain layer is a capability of that layer and all lower layers, provided to a higher layer through an interface. The services provided by each layer are independent of how these services are implemented.

TCP/IP Communication Using Socket Programming

TCP/IP Protocol

Also known as the Transmission Control/Internet Protocol, it is a network communication protocol. In fact, it includes hundreds of functional protocols, such as ICMP (Internet Control Message Protocol), FTP (File Transfer Protocol), UDP (User Datagram Protocol), ARP (Address Resolution Protocol), etc. TCP is responsible for detecting transmission issues; once a problem occurs, it sends a retransmission signal until all data is safely and correctly transmitted to the destination.

Understanding Socket

1. A socket is a socket in TCP/IP protocol, where “IP address + TCP or UDP port number” uniquely identifies a process in network communication. The “IP address + TCP or UDP port number” constitutes a socket. 2. In the TCP protocol, the two processes (client and server) establishing a connection each have a socket to identify them, and the socket pair formed by these two sockets uniquely identifies a connection. 3. The term socket itself means “socket,” thus describing a one-to-one relationship in network connections. The application layer programming interface designed for the TCP/IP protocol is called the socket API.

Socket:

In networking, it describes how different programs on a computer communicate with other computer programs. A socket is actually a special IO interface and also a file descriptor.

Sockets are divided into three categories:

Stream socket (SOCK_STREAM): Stream sockets provide reliable, connection-oriented communication streams; they use the TCP protocol, ensuring the correctness and order of data transmission.

Datagram socket (SOCK_DGRAM): Datagram sockets define a connectionless service, where data is transmitted through independent packets, is unordered, and does not guarantee reliability or error-free transmission. It uses the datagram protocol UDP.

Raw socket: Raw sockets allow direct access to lower-level protocols like IP or ICMP. They are powerful but complex to use, mainly used for the development of certain protocols.

Sockets consist of three parameters: IP address, port number, and transport layer protocol. These three parameters differentiate network communication and connections between different application processes.

Socket data structure: In C language socket programming, the sockaddr data type and sockaddr_in data type are often used to store socket information.

TCP/IP Communication Using Socket Programming

The working process of a TCP server is as follows:

The server creates a dedicated “file descriptor” to listen for the “three-way handshake” from the client, then establishes the connection.Once the connection is successfully established, the server assigns a dedicated “communication file descriptor” for communication with that client. The above communication model is due to the characteristics of TCP itself: connection-oriented, reliable, byte stream communication.

TCP/IP Communication Using Socket Programming

Communication Process

Server:

Create a socket, return the socket’s file descriptorskfd = socket()

Bind the socket file descriptor, IP, and port number together to establish a fixed correspondencebind()

Convert the socket file descriptor into a passive descriptor for passive listening of client connectionslisten()

Successfully complete the three-way handshake with the client, returning a communication descriptorfd=accept()

The server sends and receives data from the clientwrite(fd);send(fd),read(fd);recv(fd);

The four-way handshake disconnects the connection, which can be initiated by either partyclose(fd);shutdown(fd)

#include <sys/types.h>#include <sys/socket.h> // Include socket function library #include <netinet/in.h> // Include related structures of AF_INET #include <arpa/inet.h> // Include operation functions of AF_INET #include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h> /* After listening, it remains in the accept blocking state until a client connects. Input EOF to disconnect from the client, input quit to shut down the server. After reading EOF, disconnect from this client, and reading quit will shut down the server. */ #define PORT 3333 void main(){ printf(“Program starts”); int s_fd,c_fd; // Server and client socket identifiers int s_len,c_len; // Server and client message lengths struct sockaddr_in s_addr; // Server socket address struct sockaddr_in c_addr; // Client socket address int dataBytes=0; // Read message length // Message char sendbuf[BUFSIZ]; char recvbuf[BUFSIZ]; /***************************Create socket**************************/ // Socket function, returns -1 on failure //int socket(int domain, int type, int protocol); // The first parameter indicates the address type used, usually IPv4 i.e. AF_INET // The second parameter indicates the socket type: TCP generally uses SOCK_STREAM for data stream transmission // The third parameter is set to 0 s_fd = socket(AF_INET,SOCK_STREAM,0); if(s_fd < 0){ perror(“Failed to create socket”); return; } printf(“Socket created successfully”); /****************************Enable address reuse*******************/ int optval = 1; // 1 allows address reuse, 0 prohibits int optlen = sizeof(optval); setsockopt(s_fd,SOL_SOCKET,SO_REUSEADDR,&optval,optlen); /********************Initialize server socket*****************/ // htons and htonl convert port and address to network byte order // Define the domain in the server address, AF_INET indicates IPv4 s_addr.sin_family = AF_INET; // Define the server socket port s_addr.sin_port = htons(PORT); // Define the socket address // The IP can be the server’s IP, using the macro INADDR_ANY instead, which represents 0.0.0.0, indicating all addresses s_addr.sin_addr.s_addr = htonl(INADDR_ANY); /****************Bind socket settings for port number and IP***********************/ // For functions like bind and accept, the socket parameter needs to be forcibly converted to (struct sockaddr *) // bind three parameters: the file descriptor of the server socket s_len = sizeof(s_addr); // Set the message length if( bind(s_fd,(struct sockaddr*)&s_addr,s_len) < 0){ perror(“Failed to bind socket”); return; } printf(“Socket bound successfully”); /*****************Set the server’s socket to listening state*******************/ // Listen, maximum connections 10 if(listen(s_fd,10) < 0){ perror(“Listening failed”); return; } printf(“Listening successfully on port: %d”, PORT); while(1){ printf(“Waiting for connection…”); // fflush(stdin) refreshes the standard input buffer, fflush(stdout) refreshes the standard output buffer fflush(stdout); // Set the received message length c_len = sizeof(c_addr); /********************Receive client connection request*************************/ // After calling the accept function, it enters a blocking state // accept returns a socket file descriptor, so the server has two socket file descriptors, // s_fd and c_fd // s_fd remains in listening state, c_fd is responsible for receiving and sending data // c_addr is an output parameter, accept returns, outputting the client’s address and port number // c_len is an input-output parameter, the incoming is the caller’s provided buffer’s c_addr length to avoid buffer overflow. // The output is the actual length of the client address structure. // Returns -1 on error c_fd = accept(s_fd,(struct sockaddr*)&c_addr,(socklen_t*)&c_len); if(c_fd < 0){ perror(“accept failed”); continue; } printf(“New connection:”); // inet_ntoa IP address conversion function, converts network byte order IP to dotted decimal IP // Expression: char *inet_ntoa (struct in_addr); printf(“IP is %s”, inet_ntoa(c_addr.sin_addr)); printf(“Port is %d”, htons(c_addr.sin_port)); printf(“Waiting for message…”); while(1){ dataBytes=0; /*************************Receive data***********************/ printf(“——————–Reading:”); fflush(stdout); dataBytes = recv(c_fd,recvbuf,BUFSIZ,0); if( dataBytes < 0){ perror(“Reading failed”); continue; }else if(dataBytes == 0){ printf(“No message”); }else printf(“%s”,recvbuf); // Check for exit, quit, disconnect, close the client if(strncmp(recvbuf,”quit”,4) == 0){ sprintf(recvbuf,”%s”,”EOF”); send(c_fd,recvbuf,sizeof(recvbuf)+1,0); // Close connection close(s_fd); printf(“Server closed”); printf(“Program ends”); return; } // EOF, disconnect if(strncmp(recvbuf, “EOF”,3) == 0){ break; } /************************Send data*************************/ printf(“——————–Sending:”); scanf(“%s”,sendbuf); send(c_fd,sendbuf,strlen(sendbuf)+1,0); // Check for exit, quit, disconnect, close the client if(strncmp(sendbuf,”quit”,4) == 0){ sprintf(sendbuf,”%s”,”EOF”); send(c_fd,sendbuf,sizeof(sendbuf)+1,0); // Close connection close(s_fd); printf(“Program ends”); return; } // EOF, disconnect if(strncmp(sendbuf,”EOF”,3) == 0){ break; } }//while for sending and receiving messages printf(“Disconnected”); }//while accept // Close connection close(s_fd); printf(“Program ends”); return;}

Client:

Create socket fileskfd = socket()

Actively initiate a connection request to the server, three-way handshake OK after successful connection connet(skfs..)

The client sends data to the server write(skfd);send(skfd)

The client receives data from the server read(skfd);recv(skfd)

The four-way handshake disconnects the connection, which can be initiated by either partyclose(fd);shutdown(fd)

#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <netdb.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h> #define SERVER_PORT 6666 /* After connecting to the server, it will loop continuously, waiting for input. Input quit to disconnect from the server */ int main() { // The client only needs one socket file descriptor to communicate with the server int clientSocket; // Describes the server’s socket struct sockaddr_in serverAddr; char sendbuf[200]; char recvbuf[200]; int iDataNum; if ((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror(“socket”); return 1; } serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(SERVER_PORT); // Specify the server’s IP, local test: 127.0.0.1 // inet_addr() function converts dotted decimal IP to network byte order IP serverAddr.sin_addr.s_addr = inet_addr(“127.0.0.1”); if (connect(clientSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0) { perror(“connect”); return 1; } printf(“Connected to host…”); while (true) { printf(“Send message:”); scanf(“%s”, sendbuf); printf(“”); send(clientSocket, sendbuf, strlen(sendbuf), 0); if (strcmp(sendbuf, “quit”) == 0) break; printf(“Read message:”); recvbuf[0] = ‘\0’; iDataNum = recv(clientSocket, recvbuf, 200, 0); recvbuf[iDataNum] = ‘\0’; printf(“%s”, recvbuf); } close(clientSocket); return 0; }

In the above process, it can be seen that the server uses a new file descriptorfdfor communication with the client, while the client uses the descriptor created when the socket was createdskfd. Here, the server needs to support multiple client connections; that is, after each client connects to the server, the server will create a new file descriptorfdfor communication with that specific client.

End

Source: This article is a network repost, and the copyright belongs to the original author. However, due to numerous reposts, it is impossible to confirm the true original author, so only the source of the repost is indicated. If the videos, images, or texts used in this article involve copyright issues, please inform us immediately, and we will confirm the copyright based on the proof you provide and pay remuneration according to national standards or delete the content immediately! The content of this article reflects the original author’s views and does not represent the views of this public account or its authenticity.

Scan the QR code below

To help you become an excellent electrical engineer

Teacher Zuo: 18073180632 (same as WeChat)

Leave a Comment