1, Purpose of the experiment:
1. Understand the concept of network programming and socket programming related technologies;
2. Master the functions and usage of socket programming;
3. Master the basic process and method of socket programming.
2, Experimental environment:
A computer running any Linux operating system with the GNOME graphical user interface.
3, Experiment content:
PART 1 program understanding
1. Server side program server.c
Establish a server-side program server.c with the following code:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <signal.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define SERVER_PORT 6000 / / the port number can be set by yourself #define SERVER_IP "192.168.197.130" / / please set the IP address yourself according to the actual situation int listen_fd = -1; void signal_handler(int arg) { printf("close listen_fd(signal = %d)\n", arg); close(listen_fd); exit(0); } int main(int argc, const char *argv[]) { int new_fd = -1; struct sockaddr_in server; struct sockaddr_in client; socklen_t saddrlen = sizeof(server); socklen_t caddrlen = sizeof(client); signal(SIGINT, signal_handler); memset(&server, 0, sizeof(server)); memset(&client, 0, sizeof(client)); listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd < 0) { printf("socket error!\n"); return -1; } server.sin_family = AF_INET; server.sin_port = htons(SERVER_PORT); server.sin_addr.s_addr = inet_addr(SERVER_IP); if (bind(listen_fd, (struct sockaddr *)&server, saddrlen) < 0) { printf("bind error!\n"); return -1; } if (listen(listen_fd, 5) < 0) { printf("listen error!\n"); return -1; } char rbuf[256] = {0}; int read_size = 0; while (1) { new_fd = accept(listen_fd, (struct sockaddr *)&client, &caddrlen); if (new_fd < 0) { perror("accept"); return -1; } printf("new client connected.IP:%s,port:%u\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); while (1) { read_size = read(new_fd, rbuf, sizeof(rbuf)); if (read_size < 0) { printf("read error!\n"); continue; } else if (read_size == 0) { printf("client (%d) is closed!\n", new_fd); close(new_fd); break; } printf("recv:%s\n", rbuf); } } close(listen_fd); return 0; }
2. client.c
Create a client program client.c with the following code:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <signal.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define SERVER_PORT 6000 / / port #define SERVER_IP "192.168.197.130" // Server IP address int main(int argc, const char *argv[]) { int connect_fd = -1; struct sockaddr_in server; socklen_t saddrlen = sizeof(server); memset(&server, 0, sizeof(server)); connect_fd = socket(AF_INET, SOCK_STREAM, 0); if (connect_fd < 0) { printf("socket error!\n"); return -1; } server.sin_family = AF_INET; server.sin_port = htons(SERVER_PORT); server.sin_addr.s_addr = inet_addr(SERVER_IP); if (connect(connect_fd, (struct sockaddr *)&server, saddrlen) < 0) { printf("connect failed!\n"); return -1; } char buf[256] = {0}; while (1) { printf(">"); fgets(buf, sizeof(buf), stdin); if (strcmp(buf, "quit\n") == 0) { printf("client will quit!\n"); break; } write(connect_fd, buf, sizeof(buf)); } close(connect_fd); return 0; }
3. Screenshot of program operation
Compile the above program, run the server program in a terminal window, and open a terminal window to run the client program. Observe the running results of the program.
PART 2 program implementation
The function realized in PART 1 is that the client sends information to the server, which is displayed after receiving the information. On the basis of understanding the above program, the program function is extended to realize the following functions:
(1) After receiving the information, the server performs simple encryption processing, and then sends the encrypted string back to the client, which displays it. The encryption strategy is: if the character is an English character, case conversion will be performed. If it is a numeric character, the corresponding number will be added by 6 and the single digit will be taken. If it is other characters, it will remain the same. If the string received by the server is A1b2D9#6, the encrypted string is a7B8d5#2
(2) If the string received by the server is "time", encryption is not required, but the system time is sent to the client, and the client displays the received information.
1. Server side program server2.c
Establish a server-side program server2.c with the following code:
#include <stdio.h> #include <time.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <signal.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define SERVER_ Port 6000 / / the port number can be set by yourself #define SERVER_ IP "192.168.197.130" / / please set the IP address yourself according to the actual situation int listen_fd = -1; //socket descriptor void signal_handler(int arg) //Signal processing, exit in case of ctrl + c { printf("close listen_fd(signal = %d)\n", arg); close(listen_fd); exit(0); } //Get system time char* showTime() { time_t timer = time(NULL); char* showTime = asctime(localtime(&timer)); return showTime; } //Specific encryption operations void endecrypt(char *rbuf){ char *p = rbuf; while (*p != '\0'){ if((*p >= 'a' && *p <= 'z')) { *p = *p - 32; }else if(*p >= 'A' && *p <= 'Z'){ *p = *p + 32; }else if(*p >= '0' && *p <= '9'){ *p = (((*p - '0') + 6) % 10) + '0'; } p++; } } int main(int argc, const char *argv[]) { int new_fd = -1; //socket new descriptor struct sockaddr_in server; struct sockaddr_in client; socklen_t saddrlen = sizeof(server); socklen_t caddrlen = sizeof(client); signal(SIGINT, signal_handler); memset(&server, 0, sizeof(server)); //initialization memset(&client, 0, sizeof(client)); listen_fd = socket(AF_INET, SOCK_STREAM, 0); //Create the socket and update the socket descriptor if (listen_fd < 0) //Exit if socket creation fails { printf("socket error!\n"); return -1; } server.sin_family = AF_INET; //Set the protocol type to IPv4 server.sin_port = htons(SERVER_PORT); //Set port server.sin_addr.s_addr = inet_addr(SERVER_IP); //Convert the server point decimal ip to 32-bit binary network byte order and set it if (bind(listen_fd, (struct sockaddr *) &server, saddrlen) < 0) //Bind a port number and ip to associate the socket with the specified port number and ip { printf("bind error!\n"); return -1; } if (listen(listen_fd, 5) < 0) //Set listening. The maximum number of connection requests is 5 { printf("listen error!\n"); return -1; } char rbuf[256] = {0}; //buffer int read_size = 0; while (1) { new_fd = accept(listen_fd, (struct sockaddr *) &client, &caddrlen); //Accept the service request and set the latest socket descriptor if (new_fd < 0) { perror("accept"); return -1; } printf("new client connected.IP:%s,port:%u\n", inet_ntoa(client.sin_addr),ntohs(client.sin_port)); //Print out ip and port tips while (1) //Process the received data { read_size = read(new_fd, rbuf, sizeof(rbuf)); //read_size storage data size if (read_size < 0) { printf("read error!\n"); continue; } else if (read_size == 0) { printf("client (%d) is closed!\n", new_fd); close(new_fd); break; } printf("----------------received---------------\n"); printf("%s\n", rbuf); printf("----------------end!-----------------\n"); //printf("i want to test:%d len=%d\n",strncmp(rbuf, "time\n",strlen(rbuf)),strlen(rbuf)); if (!strncmp(rbuf, "time\n",strlen(rbuf) - 1)) { //Here -1 is to remove the newline character /* * When fgets writes input to rbuf, line breaks are included */ //printf("this\n"); //char *time = showTime(); //rbuf = showTime(); //printf("the time:%s\n sizeof_time:%d",time, sizeof(time)); strcpy(rbuf,showTime()); //Copy system time to rbuf write(new_fd, rbuf, sizeof(rbuf)); //Data transmission }else{ // printf("endecrypt"); endecrypt(rbuf); // printf("encrypt mess:%s\n",rbuf); write(new_fd,rbuf,sizeof(rbuf)); } printf("---------------I have finished sending---------------\n"); } } printf("i will cloes\n"); close(listen_fd); return 0; }
2. Client program client2.c
Create a client program client2.c with the following code:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <signal.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define SERVER_ Port 6000 / / port #define SERVER_ IP "192.168.197.130" / / server IP address int main(int argc, const char *argv[]) { int connect_fd = -1; struct sockaddr_in server; socklen_t saddrlen = sizeof(server); memset(&server, 0, sizeof(server)); connect_fd = socket(AF_INET, SOCK_STREAM, 0); if (connect_fd < 0) { printf("socket error!\n"); return -1; } server.sin_family = AF_INET; server.sin_port = htons(SERVER_PORT); server.sin_addr.s_addr = inet_addr(SERVER_IP); if (connect(connect_fd, (struct sockaddr *) &server, saddrlen) < 0) { printf("connect failed!\n"); return -1; } char buf[256] = {0}; while (1) { printf(">"); fgets(buf, sizeof(buf), stdin); if (strcmp(buf, "quit\n") == 0) { printf("client will quit!\n"); break; } write(connect_fd, buf, sizeof(buf)); printf("-----------------There is a message from the server----------------\n"); char sbuf[256] = {0}; int read_size = read(connect_fd, sbuf, sizeof(sbuf)); if (read_size < 0) { printf("read error!\n"); continue; } else if (read_size == 0) { printf("mess over!\n"); } printf("messg:%s\n", sbuf); printf("---------------------End of message---------------------------\n"); } close(connect_fd); return 0; }