The third experiment of computer network in Xiamen University

The third experiment of computer network in Xiamen University

preparation

1. Install the local echo service and listen to port 7. I use the ubuntu virtual machine, and the modified files are slightly different from CentOS 7.

You can see that I have configured it. (if you don't need to configure it, you can search and open the echo standard service in ubuntu)

2. It's too hard to program in ubuntu virtual machine. Vscode uses ssh connection to code and debug in vscode.

String reverse loopback (TCP iteration)

1. Achievement display:

client

The server:

The first client sends and receives normally

Second client waiting

After receiving bye, start processing the second client immediately:

2. Concrete realization

Double loop is used on the server side, with string processing inside

The client uses a single loop.

I also processed the runtime parameters so that the server and client can customize the address and port number.

3. Why do ip addresses and port numbers need byte order conversion?

The htnol () function is actually easy to understand, that is, the small end is replaced by the large end. Because the network address is the large end, but the computer memory is not necessarily the same, so it must be converted.

String reverse loopback (TCP concurrency)

1. First look at the results achieved

Server side:

Two clients

2. Three clients required by the experimental report:

3. Implementation details

  • You need to turn off the listening socket in the child process
  • Close the data socket in the parent process
  • Be sure to remember the zombie process

4.ppt problem. After the server accept s, it will return a socket for data transmission. Calling fork() will make the parent and child processes have this socket descriptor at the same time. Do you want to close the socket in the parent process branch?

The answer is yes

If not, multiple network connections will be closed after exiting the client_ WAIT

Simple chat room based on UDP socket

  1. First, I learned about threads.
  • Daemon thread: if a thread must be set as an infinite loop, if the thread does not end, it means that the whole Python program cannot end. In order to enable the python program to exit normally, set this kind of infinite loop thread as a daemon thread. When only the daemon thread is left in the program, the python program can exit normally, You don't have to worry about whether this kind of thread has completed execution, which is the meaning of guard thread.

  • Because the client needs to accept while sending. A daemon thread is created to control the reception of information.

  1. Result chart:

    The server:

    Client, detect user name login

    Client, chat content

    Client exit:

    Exception caught (server suddenly shut down)

  2. Implementation: client

    1. Create two threads, in which the acceptance information is set as the daemon thread

    2. Detect nicknames

    3. Exception capture

    4. Implementation: Server

      1. initialization
      2. Receive information
      3. Mass messaging
      4. main

source code

  • server1.c

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <error.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
    	int server_sock_listen, server_sock_data;
    	struct sockaddr_in server_addr;
    	char recv_msg[255];
    	char send_msg[255];
    	/* Create socket */
    	server_sock_listen = socket(AF_INET, SOCK_STREAM, 0);
    
    	int i,port=0;    //port
        for (i=0;i< strlen(argv[2]);i++) {
            if(argv[2][i] != 0){
                port = port*10 + argv[2][i] - '0';
            }
        }
    	/* Specify the server address */
    	server_addr.sin_family = AF_INET;
    	server_addr.sin_port = htons(port);
    	if(strcmp(argv[1],"localhost")==0){
    		server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY indicates all IP addresses of the machine
    	}
    	else {
    		server_addr.sin_addr.s_addr = htonl(inet_addr(argv[1]));
    	}
    	memset(&server_addr.sin_zero, 0, sizeof(server_addr.sin_zero)); //Zero fill
    	/* Bind socket and address */
    	bind(server_sock_listen, (struct sockaddr *)&server_addr, sizeof(server_addr));
    
    	/* Listening socket */
    	listen(server_sock_listen, 0);
    	printf("%s is listening:\n",argv[1]);
    	while(1) {
    		server_sock_data = accept(server_sock_listen, NULL, NULL);
    		printf("Accept.....\n");
    		while(1){
    			/* Receive and display messages */
    			memset(recv_msg, 0, sizeof(recv_msg)); //Receive array zeroing
    			memset(send_msg, 0, sizeof(send_msg));
    			recv(server_sock_data, recv_msg, sizeof(recv_msg), 0);
    			printf("Recv: %s\n", recv_msg);
    			if(strcmp(recv_msg,"bye")==0)
    				break;
    			int len = strlen(recv_msg);
    			for( i = 0;i < len; i++) {
    				send_msg[i] = recv_msg[len - 1 - i];
    			}
    			printf("Send: %s\n", send_msg);
    			/* send message */
    			send(server_sock_data, send_msg, strlen(send_msg), 0);
    			
    		}	
    			/* Close data socket */
    		close(server_sock_data);
    	}
    	
    	
    	/* Turn off listening socket */
    	close(server_sock_listen);
    
    	return 0;
    }
    
    
  • client1.c

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <error.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
    	int client_sock;
    	struct sockaddr_in server_addr;
        char send_msg[1000];
    	char recv_msg[255];
    
    	/* Create socket */
    	client_sock = socket(AF_INET, SOCK_STREAM, 0);
    
    	/* Specify the server address */
        int i,port=0;    //port
        for (i=0;i< strlen(argv[2]);i++) {
            if(argv[2][i] != 0){
                port = port*10 + argv[2][i] - '0';
            }
        }
    	if(!strcmp(argv[1],"localhost")) {  //input is  localhost
    		server_addr.sin_addr.s_addr = inet_addr("192.168.238.128");
    	}
    	else{
    		server_addr.sin_addr.s_addr = inet_addr(argv[1]);
    	}
    	server_addr.sin_family = AF_INET;
    	server_addr.sin_port = htons(port); 
    	memset(server_addr.sin_zero, 0, sizeof(server_addr.sin_zero)); //Zero fill
    
    	/* Connect server */
    	connect(client_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
    
    
    	/* send message */
        while(1){
            printf("Myself: ");
            scanf("%s", send_msg);
    	    send(client_sock, send_msg, strlen(send_msg), 0);
    		if (strcmp(send_msg,"bye")==0) {
    			break;
    		}
    	/* Receive and display messages */
    	    memset(recv_msg, 0, sizeof(recv_msg)); //Receive array zeroing
    	    recv(client_sock, recv_msg, sizeof(recv_msg), 0);
    	    printf("Recv: %s\n", recv_msg);
    
        }
    	/* Close socket */
    	close(client_sock);
    
    	return 0;
    }
    
    
  • server2.c

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <error.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <sys/wait.h>
    
    int main(int argc, char *argv[])
    {
    	int server_sock_listen, server_sock_data;
    	struct sockaddr_in server_addr;
    	char recv_msg[255];
    	char send_msg[255];
    	/* Create socket */
    	server_sock_listen = socket(AF_INET, SOCK_STREAM, 0);
    
    	int i,port=0;    //port
        for (i=0;i< strlen(argv[2]);i++) {
            if(argv[2][i] != 0){
                port = port*10 + argv[2][i] - '0';
            }
        }
    	/* Specify the server address */
    	server_addr.sin_family = AF_INET;
    	server_addr.sin_port = htons(port);
    	if(strcmp(argv[1],"localhost")==0){
    		server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY indicates all IP addresses of the machine
    	}
    	else {
    		server_addr.sin_addr.s_addr = htonl(inet_addr(argv[1]));
    	}
    	memset(&server_addr.sin_zero, 0, sizeof(server_addr.sin_zero)); //Zero fill
    	/* Bind socket and address */
    	bind(server_sock_listen, (struct sockaddr *)&server_addr, sizeof(server_addr));
    
    	/* Listening socket */
    	listen(server_sock_listen, 0);
    
    	printf("%s is listening:\n",argv[1]);
    	struct sockaddr_in client_addr;
        socklen_t client_len = sizeof(client_addr);
        while(1) {
    		server_sock_data = accept(server_sock_listen, (struct sockaddr*)&client_addr, 
                    &client_len);
            signal(SIGCHLD, SIG_IGN);
    		pid_t pid = fork();
            if(pid < 0){
                printf("error in fork!\n");
            }
            else if (pid == 0) {
                close(server_sock_listen);
                while(1){
                    /* Receive and display messages */
                    memset(recv_msg, 0, sizeof(recv_msg)); //Receive array zeroing
                    memset(send_msg, 0, sizeof(send_msg));
                    char ip[64];
                    
                    recv(server_sock_data, recv_msg, sizeof(recv_msg), 0);
                    printf("Recv: %s\n", recv_msg);
                    printf("Accept from %s : %d\n",inet_ntop(AF_INET,
                        &client_addr.sin_addr.s_addr,ip,sizeof(ip)),ntohs(client_addr.sin_port));
                    if(strcmp(recv_msg,"bye")==0)
                    {
                        printf("Close from %s : %d\n",inet_ntop(AF_INET,
                        &client_addr.sin_addr.s_addr,ip,sizeof(ip)),ntohs(client_addr.sin_port));
                        break;
                    }
                    int len = strlen(recv_msg);
                    for( i = 0;i < len; i++) {
                        send_msg[i] = recv_msg[len - 1 - i];
                    }
                    printf("Send: %s\n", send_msg);
                    /* send message */
                    send(server_sock_data, send_msg, strlen(send_msg), 0);
    		    }
                return 0;	
            }
            else{
                    /* Close data socket */
                close(server_sock_data);
            }
    	}
    	/* Turn off listening socket */
    	close(server_sock_listen);
    
    	return 0;
    }
    
    
  • serverchatroom.py

    from socket import *
    from threading import Thread
    import sys
    
    class Server:
    
        user_info = {}
        _ServerOpen = True
    
        def __init__(self,server_port):
            self.serverPort = server_port
            self.udpSocket = socket(AF_INET,SOCK_DGRAM)
            self.udpSocket.bind(self.serverPort)
            self.thread_recv = Thread(target=self.recv_msg)
            self.thread_send = Thread(target=self.send_msg)
    
        def recv_msg(self):
            while True:
                try:
                    recv_data,dest_ip = self.udpSocket.recvfrom(1024)
                    if not self._ServerOpen:
                        self.udpSocket.sendto('exit'.encode(), dest_ip)
                        name = self.user_info[dest_ip]
                        self.sent_to_all('system: %s Chat exited'%name)
                        while len(self.user_info):
                            recv_data,dest_ip = self.udpSocket.recvfrom(1024)
                            self.udpSocket.sendto('exit'.encode(),dest_ip)
                            name = self.user_info[dest_ip]
                            del self.user_info[dest_ip]
                            self.send_to_all(' System:%s Chat exited'%name)
                        print('The server is down')
                        self.udpSocket.close()
                        break
                    #Process login
                    info_list = str(recv_data.decode()).split(' ')
                    if info_list[0] == 'login':
                        if info_list[1] not in self.user_info.values():
                            self.udpSocket.sendto('OK'.encode(),dest_ip)
                            self.send_to_all('system:%s Enter the chat room'%info_list[1])
                            self.user_info[dest_ip] = info_list[1]
                        else:
                            self.udpSocket.sendto('Used name'.encode(), dest_ip)
                    
                    elif info_list[0] == 'exit' :
                        message = '%s Quit the chat room'%self.user_info[dest_ip]
                        self.send_to_all(message)
                        del self.user_info[dest_ip]
                    else:
                        name = self.user_info[dest_ip]
                        message = name + ': '+ recv_data.decode()
                        self.send_to_all(message)
                except (KeyboardInterrupt,EOFError):
                    print('-------Server interrupt--------')
                    break
    
        def send_msg(self):
            while self._ServerOpen:
                try:
                    data_ifno = input()
                    if data_ifno == 'exit':
                        self._ServerOpen = False
                        print('The server is shutting down')
                        self.send_to_all('The server has been shut down. Please go offline')
                        break
                except (KeyboardInterrupt,EOFError):
                    print('------Server interrupt--------')
                    break
    
        def start(self):
            print('Server started,ip Address:'+self.serverPort[0]+'Port number:%d' %self.serverPort[1])
            self.thread_recv.start()
            self.thread_send.start()
            self.thread_recv.join()
            self.thread_send.join()
        
        def send_to_all(self,message):
            for i in self.user_info.keys():
                self.udpSocket.sendto(message.encode(),i)
    
    if __name__=='__main__':
        port = int(input('Please enter the port number to bind'))
        server1 = Server(('192.168.1.101', port))
        server1.start()
    
  • clientchatroom.py

    from socket import *
    from threading import Thread
    from requests.exceptions import ConnectionError, ReadTimeout
    import time
    
    class Client():
    
        def __init__(self,server_post):
        #    self.clientPort = client_post
            self.serverPort = server_post
            self.udpSocket = socket(AF_INET,SOCK_DGRAM)
        #    self.userName = name
            self.thread_recv = Thread(target=self.recvMsg,daemon=True)
            self.thread_send = Thread(target=self.sendMsg)
    
        def start(self):
            name = input('Please enter a nickname:')
            message = 'login '+name
            self.udpSocket.sendto(message.encode(), self.serverPort)
            while True:
                try:
                    recvData,destIP = self.udpSocket.recvfrom(1024)
                    if recvData.decode() == 'OK':
                        print('Welcome to the chat room. To exit the chat room, please enter exit')
                        break
                    else:
                        name = input('The nickname is already occupied. Please re-enter the nickname:')
                        message = 'login '+name
                        self.udpSocket.sendto(message.encode(),self.serverPort)
                except (ConnectionResetError,TypeError):
                    print('------Server connection failed--------')
            self.thread_recv.start()
            self.thread_send.start()
            self.thread_send.join()
    
        def recvMsg(self):
            while True:
                try:
                    recvData,destIp = self.udpSocket.recvfrom(1024)
                    if recvData.decode() == 'exit' and destIp == self.serverPort:
                        print('client is closed\n')
                        self.udpSocket.close()
                        break
                    print(recvData.decode())
                except (ConnectionResetError,TypeError):
                    print('------Server connection failed--------')
                
        def sendMsg(self):
            while True:
                    dataInfo = input()
                    self.udpSocket.sendto(dataInfo.encode(),self.serverPort)
                    if dataInfo == 'exit':
                        print('-------Connection closed-------')
                        break
    
    if if__name__=='__main__':
        	postAdd = input('Please enter the name of the server IP address: ')
        	postNum = int(input('Please enter the port number of the server: '))
        	client = Client((postAdd,postNum))
       		client.start()
    
         
    

Tags: Python socket computer networks udp

Posted on Mon, 22 Nov 2021 03:22:15 -0500 by zeropaid