Table of contents
1. Four high-performance IO models in server programming
1. The difference between blocking IO and non-blocking IO
2. How to set the non-blocking attribute to the file descriptor----fcntl() ----- man 2 fcntl
1. Monitor multiple socket IO ports at the same time
4. Multiplexed function interface -------select -----man 2 select
1. Four high-performance IO models in server programming
1. Block IO
1)read(fd,buf) ; recv(fd) ; recvfrom(fd)
These functions themselves do not have blocking attributes, but the blocking attribute of the file descriptor itself causes the execution of this function to be blocked.
2) By default, the socket sockets established under Linux are blocked.
2. Non-blocking IO
1) Add non-blocking attribute to file descriptor
2) Because of the non-blocking property, the socket is constantly asked if data arrives
3. Multiplexing
1) Operate on multiple IO ports at the same time (that is, listen to several sockets at the same time)
2) It can detect whether the data arrives within the specified time
4. Signal drive
1) It belongs to asynchronous communication mode
2) When data arrives in the socket, notify the user by sending a signal
2. Blocking IO
Read blocking: When there is no data to read in the data buffer, calling read/recv/recvfrom will block infinitely.
Write blocking: When the remaining size of the buffer is less than the amount of data written, write blocking will occur until the data in the buffer is read

3. Non-blocking IO
1. The difference between blocking IO and non-blocking IO
2. How to set the non-blocking attribute to the file descriptor----fcntl() ----- man 2 fcntl
#include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ... /* arg */ );
parameter
fd : Which file do you want to set, pass in the file descriptor of this file
cmd: command word to request control
arg: Whether or not to fill in this parameter depends on the second parameter
The second parameter:

for example:
int fd = open("xxx"); int status = fcntl(fd, F_GETFL ); //get the status of the file descriptor status |= O_NONBLOCK ;//Add non-blocking properties on the basis of the original fcntl(fd, F_SETFL,status); //Set the state of the variable status to the file descriptor
return value
F_GETFL Value of file status flags.
F_SETFL
Returns 0 successfully
Returns -1 on failure
Example 1: Set a non-blocking attribute to a socket to see if the socket will still block waiting for client connections?

Example 2: Using TCP communication Modify it to be non-blocking
1 #include<stdio.h> 2 #include <sys/socket.h> 3 #include <sys/types.h> /* See NOTES */ 4 #include <netinet/in.h> 5 #include <arpa/inet.h> 6 #include <string.h> 7 #include <unistd.h> 8 #include <fcntl.h> 9 #define OWNADDR "192.168.14.3" //My own computer's ip address 10 #define OWNPORT 20000 //The port number of this program on my own computer 12 int main() 13 { printf("current server IP:%s Port:%u\n",OWNADDR,OWNPORT); 14 //1. Buy a mobile phone (build a socket) 15 int socketfd = socket(AF_INET, SOCK_STREAM, 0); 16 if(socketfd == -1) 17 { 18 printf("No money....,fail\n"); 19 return -1; 20 } 21 //Because the port number will not be released in time after the server exits immediately //At this time, if the server runs again immediately, the port number will be occupied, causing the server to fail to assign the port number and the connection to fail. 23 //So setting the port number can reuse 24 int optval = 1; 25 setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR,&optval, sizeof(optval)); 26 27 //2. Bind your own phone number (bind your own IP address and port number) 28 //Define an IPV4 structure variable, initialize your own IP address and port number 29 struct sockaddr_in ownAddr; 30 ownAddr.sin_family = AF_INET;/*Address family IPV4*/ 31 ownAddr.sin_port = htons(OWNPORT); //htons converts the local port number to the network port number 32 ownAddr.sin_addr.s_addr = inet_addr(OWNADDR); //Convert local IP address to network IP address 33 34 bind(socketfd, (struct sockaddr *)&ownAddr,sizeof(struct sockaddr_in)); 35 36 //3. Set the ringtone (listen) listen 37 listen(socketfd,5); 38 39 //4. Waiting for the call (blocking the connection of the receiving client) 40 printf("waiting for client to connect.......\n"); 41 //Define an IPV4 structure variable to store the IP address and port number of the connected client 42 struct sockaddr_in clientAddr; 43 //If you want to get the IP address and port number of the other party, the third parameter must pass in the size of the structure 44 int len = sizeof(struct sockaddr_in); 45 46 //Set the non-blocking attribute to socketfd 47 int status = fcntl(socketfd,F_GETFL);//get the attributes of this socket file descriptor 48 //Set one of the attributes of the resulting file descriptor to non-blocking 49 status |= O_NONBLOCK; 50 int ret = fcntl(socketfd,F_SETFL,status);//Set the state of the variable status to the file descriptor 51 if(ret == -1) 52 { 53 printf("fcntl error\n"); 54 55 } 56 while(1) 57 { 58 //At this point, it is non-blocking and will continue to loop 59 int newClientFd = accept(socketfd,(struct sockaddr*)&clientAddr,&len); 60 if(newClientFd != -1) 61 { //printf("A client is connected.......\n"); 63 //Print the IP address and port number of the connected client, and convert the network byte order to the local byte order 64 printf("connected client IP:%s port No:%u\n",inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port)); 65 } 66 //printf("11111111111\n"); 67 } 68 69 //5. Close 70 close(socketfd); 71 //close(newClientFd); 72 73 return 0; 74 75 }
Example 1: Write a server that can accept up to 1000 client connections and can accept connections at any time.
As long as the client connected to the server has data arriving, the data is printed out. Requires non-blocking IO implementation. Can't open thread
Idea: Accept up to 20 client connections ---> User connected successfully ---> Judgment full --> connection refused --> disconnect this user 2 ---> User connected successfully ---> underage --> save socket to array 3 4 5 struct ciient{ int clifd[1000]; //Socket 6 for connected user int count; //Total number of connected users 7 8 } 9 10 non-blocking IO: Keep asking these connected users and if anyone else is connecting! 11 while(1) 12 { 13 int clifd[20]; ??? Is there any data coming? 14 }
1 #include<stdio.h> 2 #include<stdio.h> 3 #include <sys/types.h> /* See NOTES */ 4 #include <sys/socket.h> 5 #include <sys/socket.h> 6 #include <arpa/inet.h> 7 #include <unistd.h> 8 #include<stdlib.h> 9 #include <string.h> 10 #include <errno.h> 11 #include <signal.h> 12 #include <sys/wait.h> 13 #include <fcntl.h> 14 15 //#include <pthread.h> 16 17 #define SERVER_PORT 9999 18 19 20 struct client{ int clientFd_Array[1000] ;//Store socket file descriptors for all connected clients 21 int clientCount; //Total number of connected clients 22 23 }; 24 25 26 void sys_err(const char*err) 27 { fprintf(stderr,"%s\n",strerror(errno)); 28 exit(0); 29 30 } 31 32 33 int main() 34 { int ret; 35 struct sockaddr_in clientAddr;//Store the IP address and port number of the connected client 36 int len = sizeof(struct sockaddr_in); 37 struct client clientManager; //Client Struct Management Variables 38 39 //initialize struct 40 clientManager.clientCount = 0; 41 42 printf("server Port:%d PID:%d \n",SERVER_PORT,getpid()); 43 44 //1. Create a socket 45 int socketFd = socket(AF_INET,SOCK_STREAM, 0); 46 if(socketFd == -1){ 47 sys_err("socket error"); 48 } 49 //Port multiplexing 50 int optval = 1; 51 setsockopt(socketFd,SOL_SOCKET,SO_REUSEADDR,&optval, sizeof(optval)); 52 53 //2. Bind your own IP address and port number 54 struct sockaddr_in serverAddr; 55 serverAddr.sin_family = AF_INET; 56 serverAddr.sin_port = htons(SERVER_PORT);//short 57 serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); 58 59 ret = bind(socketFd,(struct sockaddr*)&serverAddr,sizeof(struct sockaddr_in)); 60 if(ret == -1){ 61 sys_err("bind error"); 62 } 63 64 //3. Setting monitoring 65 listen(socketFd,128); 66 67 //Set the listening socket to non-blocking attribute 68 //The first step is to get the original attributes of the original socket 69 int state = fcntl(socketFd,F_GETFL); 70 //The second step is to add a non-blocking attribute on the basis of the original 71 state |= O_NONBLOCK; // state = state | O_NONBLOCK 72 //The third step is to set the new attribute back to the file descriptor 73 fcntl(socketFd,F_SETFL,state); 74 75 while(1){ 76 //4. Receive new client connections.... 77 int newClientFd = accept(socketFd, (struct sockaddr*)&clientAddr,&len); 78 if(newClientFd > 0) //Indicates that a client is connected 79 { 80 printf("A new client is connected IP:%s Port:%hu newClientFd:%d\n", 81 inet_ntoa(clientAddr.sin_addr), 82 ntohs(clientAddr.sin_port), 83 newClientFd); 84 85 //Set the attribute of the client file descriptor to non-blocking attribute 86 //The first step is to get the original attributes of the original socket 87 int state = fcntl(newClientFd,F_GETFL); 88 //The second step is to add a non-blocking attribute on the basis of the original 89 state |= O_NONBLOCK; // state = state | O_NONBLOCK 90 //The third step is to set the new attribute back to the file descriptor 91 fcntl(newClientFd,F_SETFL,state); 92 93 94 //Store each connected client in a struct variable 95 clientManager.clientFd_Array[clientManager.clientCount] = newClientFd; 96 clientManager.clientCount++; 97 } 98 99 //Poll one by one to see if the connected client has data reaching 100 for(int i=0; i<clientManager.clientCount; i++){ 101 char buf[1024] = {0}; 102 int ret = recv(clientManager.clientFd_Array[i],buf, sizeof(buf), 0); 103 if(ret == 0) //Client disconnected 104 { 105 //printf("Client exited....\n"); 106 //sleep(1); 107 break; 108 } 109 else if(ret > 0) //There is data coming, you can print 110 { 111 printf("recv:%s\n",buf); 112 } 113 } 114 115 116 } 117 118 //close 119 close(socketFd); return 0; 123 124 }
4. Multiplexing
1. Monitor multiple socket IO ports at the same time
Blocking IO ----> can only listen to one socket at the same time
Non-blocking IO--->Always polling to ask if there is data arriving at the IO port, which is a waste of CPU resources
2. What is multiplexing
It is to add the file descriptors that need to be monitored to a set in advance, and then wait for a specified time or an infinite time. If there is no data change in the file descriptor in the set within the specified time, it means that the reception is overtime, and the next specified time is entered to wait again. Once the file descriptors in the set have data changes, other file descriptors without data changes will be excluded from the set and enter the next waiting state again.
3. Features
Monitor multiple IO ports at the same time.
4. Multiplexed function interface -------select -----man 2 select
#include <sys/select.h> 2 #include <sys/time.h> 3 #include <sys/types.h> 4 #include <unistd.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); //poll epoll
parameter:
nfds: The value of the largest file descriptor in the three sets + 1, because this parameter will tell the kernel how many file descriptors are detected before the state
readfds: Monitors the arrival of read data to the file descriptor set, incoming and outgoing parameters
writefds: monitor write data arriving at the file descriptor set, incoming and outgoing parameters
exceptfds: Monitor the occurrence of exceptions to the file descriptor set, such as out-of-band data arrival exceptions, incoming and outgoing parameters
timeout: set blocking waiting time, 3 cases
1. Set NULL, wait forever, this function is blocking (wait infinitely until the state of the file descriptor changes)
2. Set timeval and wait for a fixed time
3. Set the time in timeval to 0, return immediately after checking the description word, and poll
---> If this parameter is filled with NULL, it means that this function is blocking (waiting indefinitely until there is a file descriptor status)
state changes)
struct timeval { 2 long tv_sec; /* seconds second*/ 3 long tv_usec; /* microseconds microseconds*/ 4 }; 5 void FD_CLR(int fd, fd_set *set); //Clear fd in the file descriptor set to 0 6 int FD_ISSET(int fd, fd_set *set); //Test whether the fd in the file descriptor set is set to 1 7 void FD_SET(int fd, fd_set *set); //Put the fd position 1 8 in the file descriptor set void FD_ZERO(fd_set *set); //Clear all bits in the file descriptor set to 0
return value: success data arrives ---->The total number of file descriptors whose state has changed No data arrived, timeout-->0 fail -1 Notice: 1,select The number of file descriptors that can be monitored is limited by FD_SETSIZE,Generally 1024, simply change the file descriptor opened by the process The number cannot be changed select Monitor the number of files 2,Used when solving clients below 1024 select is fine, but if there are too many linked clients, select polling mode type, will greatly reduce the server response efficiency 3,Can be cross-platform
/*4_accept Non-blocking IO polling server*/ #include <stdio.h> #include <unistd.h> #include <string.h> /*socket*/ #include <sys/types.h> /* See NOTES */ //man 2 socket /*inet_addr*/ #include <sys/socket.h> //man 3 inet_addr #include <netinet/in.h> #include <arpa/inet.h> /*fcntl*/ #include <fcntl.h> //man 2 fcntl #define SERVER_IP "192.168.11.2" #define SERVER_PORT 60000 int main(int argc,char **argv) { //create socket int socket_fd = socket(AF_INET,SOCK_STREAM,0); if(socket_fd < 0) { perror("socket fail"); return -1; } //So setting the port number can be reused, these two statements are placed before bind bind int optval = 1; setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,&optval, sizeof(optval)); //bind struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); bind(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)); //monitor listen(socket_fd,20); //Add non-blocking attribute to socket_fd socket int status = fcntl(socket_fd, F_GETFL); //Get the status of the file descriptor --> F_GETFL status |= O_NONBLOCK ;//Add non-blocking properties on the basis of the original fcntl(socket_fd, F_SETFL,status); //Set the state of the variable status to the file descriptor //take over int socket_client; int client_cnt[20],cnt=0,j=0; //Initialize the client's socket for(j=0;j<20;j++) { client_cnt[j] = -1; } struct sockaddr_in client_addr; socklen_t addrlen = sizeof(client_addr); int ret; char buf[1024] = {0}; //Can accept multiple clients at the same time without opening processes and threads while(1) { //Because the socket_fd socket has the blocking attribute, the accept function is blocked socket_client = accept(socket_fd,(struct sockaddr *)&client_addr,&addrlen); if(socket_client != -1) { char *ip = inet_ntoa(client_addr.sin_addr); int port = ntohs(client_addr.sin_port); printf("A new client is online [ip:%s port:%d]\n",ip,port); //Set socket_client as a non-blocking attribute and store it in an array int status = fcntl(socket_client, F_GETFL); //Get the status of the file descriptor --> F_GETFL status |= O_NONBLOCK ;//Add non-blocking properties on the basis of the original fcntl(socket_client, F_SETFL,status); //Set the state of the variable status to the file descriptor //Store all client sockets in an array client_cnt[cnt++] = socket_client; //cnt represents the valid client sockets in the array //printf("cnt = %d\n",cnt); } #if 0 //View all client sockets in the array (for debugging) for(j=0;j<20;j++) { printf("%d ",client_cnt[j]); } printf("\n"); printf("waiting for connection....\n"); sleep(1); #endif //Traverse all sockets in the array (loop to receive data from each client) for(j=0;j<cnt;j++) //cnt is a valid socket in the array { memset(buf,0,sizeof(buf)); //By default, the recv function is a blocking attribute, but now recv is non-blocking ret = recv(client_cnt[j],buf,sizeof(buf),0); if(ret > 0) //print only valid data printf("buf:%s ret:%d\n",buf,ret); } } //close the socket close(socket_fd); } /*5_accept Non-blocking IO polling server ip and port*/ #include <stdio.h> #include <unistd.h> #include <string.h> /*socket*/ #include <sys/types.h> /* See NOTES */ //man 2 socket /*inet_addr*/ #include <sys/socket.h> //man 3 inet_addr #include <netinet/in.h> #include <arpa/inet.h> /*fcntl*/ #include <fcntl.h> //man 2 fcntl #define SERVER_IP "192.168.11.2" #define SERVER_PORT 60000 struct client_info { int cli_socket; struct sockaddr_in cli_addr; }; int main(int argc,char **argv) { //create socket int socket_fd = socket(AF_INET,SOCK_STREAM,0); if(socket_fd < 0) { perror("socket fail"); return -1; } //So setting the port number can be reused, these two statements are placed before bind bind int optval = 1; setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,&optval, sizeof(optval)); //bind struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); bind(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)); //monitor listen(socket_fd,20); //Add non-blocking attribute to socket_fd socket int status = fcntl(socket_fd, F_GETFL); //Get the status of the file descriptor --> F_GETFL status |= O_NONBLOCK ;//Add non-blocking properties on the basis of the original fcntl(socket_fd, F_SETFL,status); //Set the state of the variable status to the file descriptor //Initialize the client's socket int cnt = 0,j=0; struct client_info info[100]; for(j=0;j<100;j++) info[j].cli_socket = -1; struct sockaddr_in client_addr; socklen_t addrlen = sizeof(client_addr); //take over int socket_client; int ret; char buf[1024] = {0}; //Can accept multiple clients at the same time without opening processes and threads while(1) { //Because the socket_fd socket has the blocking attribute, the accept function is blocked socket_client = accept(socket_fd,(struct sockaddr *)&client_addr,&addrlen); if(socket_client != -1) { char *ip = inet_ntoa(client_addr.sin_addr); int port = ntohs(client_addr.sin_port); printf("A new client is online [ip:%s port:%d]\n",ip,port); //Set socket_client as a non-blocking attribute and store it in an array int status = fcntl(socket_client, F_GETFL); //Get the status of the file descriptor --> F_GETFL status |= O_NONBLOCK ;//Add non-blocking properties on the basis of the original fcntl(socket_client, F_SETFL,status); //Set the state of the variable status to the file descriptor //Store all client sockets in an array //cnt represents the valid client sockets in the array info[cnt].cli_socket = socket_client; info[cnt].cli_addr = client_addr; cnt++; } #if 0 //View all client sockets in the array (for debugging) for(j=0;j<20;j++) { printf("%d ",info[j].cli_socket); } printf("\n"); printf("waiting for connection....\n"); sleep(1); #endif //Traverse all sockets in the array (loop to receive data from each client) for(j=0;j<cnt;j++) //cnt is a valid socket in the array { memset(buf,0,sizeof(buf)); //By default, the recv function is a blocking attribute, but now recv is non-blocking /* ret = recv(client_cnt[j],buf,sizeof(buf),0); if(ret > 0) //print only valid data printf("buf:%s ret:%d\n",buf,ret); */ ret = recv(info[j].cli_socket,buf,sizeof(buf),0); if(ret > 0) //print only valid data printf("[ip:%s port:%d]buf:%s ret:%d\n", inet_ntoa(info[j].cli_addr.sin_addr), ntohs(info[j].cli_addr.sin_port), buf,ret); } } //close the socket close(socket_fd); } /*6_Implementing a TCP server using multiplexed select*/ #include<stdio.h> #include<stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include<stdlib.h> #include <string.h> #include <errno.h> #include <signal.h> #include <sys/wait.h> #include <fcntl.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> #define SERVER_IP "192.168.11.2" #define SERVER_PORT 60000 void sys_err(const char*err) { fprintf(stderr,"%s\n",strerror(errno)); exit(0); } int main() { int ret,max_fd,i=0,imax=0; int client[FD_SETSIZE]; //Store the file descriptors of all clients//The macro system has been defined The total number of file descriptors is 1024 struct sockaddr_in clientAddr;//Store the IP address and port number of the connected client int len = sizeof(struct sockaddr_in); printf("server Port:%d PID:%d \n",SERVER_PORT,getpid()); //1. Create a socket (listen socket) int socket_fd = socket(AF_INET,SOCK_STREAM, 0); if(socket_fd == -1) { sys_err("socket error"); //perror("bind"); //The release of the two error bars is the same } //Port multiplexing int optval = 1; setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&optval, sizeof(optval)); //2. Bind your own IP address and port number struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT);//short //server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //Indicates any IP address of the machine server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); ret = bind(socket_fd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr_in)); if(ret == -1) { sys_err("bind error"); } //3. Set up monitoring listen(socket_fd,128); //Define a set of file descriptors fd_set rset,allset; //empty collection FD_ZERO(&allset); FD_SET(socket_fd, &allset); //Add the listening socket to the collection //The largest file descriptor, before no client comes in, the largest file descriptor value is socket_fd max_fd = socket_fd; //Initialize to -1 to initialize the array holding client sockets for(int k=0; k<FD_SETSIZE; k++) { client[k] = -1; } //set blocking time struct timeval t; t.tv_sec = 5; t.tv_usec = 0; while(1) { rset = allset; //Every time you loop, you need to reset the select collection //Multiplexing, listening to the status of multiple socket file descriptors at the same time -- blocking listening //nready represents the total number of file descriptors whose status has changed, (not how many descriptors are stored in it) int nready = select(max_fd+1,&rset, NULL,NULL, NULL); if(nready == -1) { perror("select error"); break; } //The program comes here, indicating that the state of the file descriptors in the collection must have changed //If the file descriptor of the listening socket has changed, it means that a new client must be connected. if(FD_ISSET(socket_fd, &rset)) { //Receive new clients int new_clientfd = accept(socket_fd, (struct sockaddr*)&clientAddr,&len); printf("A new client is connected IP:%s Port:%hu new_clientfd:%d\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port), new_clientfd); //Add the new client file descriptor to the set FD_SET(new_clientfd, &allset); //update file descriptor max if(new_clientfd > max_fd) max_fd = new_clientfd; //Add the connected client file descriptor to the array for(i=0; i<FD_SETSIZE; i++) { if(client[i] <0 ) { client[i] = new_clientfd; break; } } //imax = i;//Store the largest subscript value in the client socket array (you can use this value to record the number of your clients) //Indicates that only the listening socket file descriptor changes in the set if(--nready == 0) continue; } //The program goes here, indicating that there is a client sending data for(i=0; i<FD_SETSIZE; i++) { if(client[i] <0) continue; //Indicates that the client has sent data, //The state of the client socket changes, the sentence if(FD_ISSET(client[i], &rset)) is established if(FD_ISSET(client[i], &rset)) { char buf[1024] = {0}; int ret = read(client[i],buf,sizeof(buf)); if(ret == 0) //The client is disconnected { printf("A client is disconnected.....\n"); close(client[i]);//close file descriptor FD_CLR(client[i],&allset);//remove this client from the file collection client[i] = -1; //The array position corresponding to the file descriptor is set to -1 } printf("recv:%s\n",buf); //Indicates that all changed file descriptors have been processed by us, then exit if(--nready == 0) break; } } } //closure close(socket_fd); return 0; }
Client.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> /*socket*/ #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> /*ip*/ #include <netinet/in.h> //man 3 inet_addr #include <arpa/inet.h> //IP address of the server #define SERVER_IP "192.168.11.2" #define SERVER_PORT 60000 int main(int argc,char **argv) { //Create a socket --socket int socket_fd; //AF_INET-->ipv4 SOCK_STREAM-->tcp socket_fd = socket(AF_INET,SOCK_STREAM,0); if(socket_fd < 0) { perror("socket fail"); return -1; } printf("socket_fd = %d\n",socket_fd); //Fill IP address (server) -- new structure struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; //ipv4 server_addr.sin_port = htons(SERVER_PORT);//host to net (local port number to network port number) server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);//Convert local IP to network IP //connect to the server int ret; ret = connect(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)); if(ret < 0) { printf("connect fail\n"); return -1; } //send data to server char buf[1024] = {0}; while(1) { memset(buf,0,sizeof(buf)); scanf("%s",buf); ret = send(socket_fd,buf,strlen(buf),0); printf("send success ret:%d\n",ret); } //close the socket close(socket_fd); return 0; }