基于数据报套接字的服务器回射程序设计:分别以循环服务器和并发服务器实现

目录

  • 一、基于数据报套接字的服务器回射程序设计
    • 无连接的数据报套接字回射客户端 设计思路
    • 循环服务器 设计思路
    • 并发服务器 设计思路
  • 二、代码实现
    • 客户端代码(循环服务器对应的)
    • 循环服务器端代码
    • 并发服务器端代码
    • 客户端代码(并发服务器对应的)
  • 三、用户使用说明(输入 / 输出规定)
  • 四、运行结果
    • 回射程序,客户端和循环服务器运行结果
    • 回射程序,客户端和并发服务器运行结果

一、基于数据报套接字的服务器回射程序设计

基于数据报套接字的服务器回射程序设计内容:

编写一服务器程序和客户程序,如图1,要求客户每输入一行数据,服务器接收后加上echo:回送给客户程序,当客户输入“q”后退出。

要求分别以循环服务器和并发服务器实现。
基于数据报套接字的服务器回射程序设计:分别以循环服务器和并发服务器实现_第1张图片
图1 回射程序

无连接的数据报套接字回射客户端 设计思路

基于数据报套接字的服务器回射程序设计:分别以循环服务器和并发服务器实现_第2张图片

循环服务器 设计思路

基于数据报套接字的服务器回射程序设计:分别以循环服务器和并发服务器实现_第3张图片

并发服务器 设计思路

为了解决接收客户端的多次交互的请求的问题,在客户端发出第一个“ASK Port”请求后服务器为每个客户创建一个的新的套接字,在其上 bind 一个临时端口,创建一个子进程使用该套接字发送对该客户的所有应答。要求客户端查看服务器第一个应答的中的源端口号,并把本请求的后续数据报发送到该端口。

二、代码实现

客户端代码(循环服务器对应的)

#define NETWORK1_2_1_A_COMM_H
#define NETWORK1_2_1_A_COMM_H
#include 
#include 
#include 
#include 
#include 
#include 
#pragma comment(lib, "ws2_32.lib")
#define MAXLINE 4096     // 接收缓冲区长度
#define LISTENQ 1024     // 监听队列长度
#define SEVER_PORT 13442 // 端口 
/*套接字初始化*/ 
int StartUp()
{
    WORD w_version = MAKEWORD(2, 2);
    WSADATA wsa_data;
    int res = WSAStartup(w_version, &wsa_data);
    if (res != 0)
    {
    	printf("WSAStartup Error:%d\n",WSAGetLastError());
        return -1;
    }//版本号错误 
    if (LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2)
    {
       	printf("WSAStartup Error:%d\n",WSAGetLastError());
        WSACleanup();
        return -1;
    }

    return 0; //成功返回0 
}
/*释放资源*/ 
int cleanUp()
{
    int res = WSACleanup();
    if (res == SOCKET_ERROR)
    {
    	printf("WSACleanup Error:%d",WSAGetLastError()); 
        return -1;
    }
    return 0;
}
/*断开连接,释放资源*/ 
int closeConn(SOCKET sock_conn)
{
    int res = closesocket(sock_conn); //关闭连接
    if (res == SOCKET_ERROR)
    {
    	printf("关闭连接失败%d\n",WSAGetLastError());
        return -1;
    }
    res = cleanUp();
    return res;
}
/*连接服务器并绑定*/
SOCKET udpClientInit(char *server_ip, u_short port, sockaddr_in &server_addr, bool flag)
{
    int res = -1;
    SOCKET sock_conn;
    // 绑定地址、端口
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr.S_un.S_addr = inet_addr(server_ip);
    //创建套接字
    sock_conn = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_conn == INVALID_SOCKET)
    {
    	printf("连接初始化失败%d\n",WSAGetLastError());
        cleanUp();
        return -1;
    }

    if (flag)
    {
        // 请求连接服务器
        res = connect(sock_conn, (struct sockaddr *)&server_addr, sizeof(server_addr));
        if (res == SOCKET_ERROR)
        {
            // 连接服务器失败
            printf("连接失败:%d\n",WSAGetLastError()); 
            closeConn(sock_conn);
            return -1;
        }
    }

    return sock_conn; //连接成功
}
int getline(char s[],int lim)
{
    int c,i;
    i=0;
    while((c=getchar())!=EOF&&c!='\n'&&i<lim-1)
        s[i++]=c;
    s[i]='\0';
    return i;
}
/*回射客户端发送接收程序*/
int udpEchoClient(SOCKET sock_conn, SOCKADDR *server_addr, int addr_len)
{
    int res = -1;
    char send_data[MAXLINE], recv_data[MAXLINE];
    memset(send_data, 0, MAXLINE);
    memset(recv_data, 0, MAXLINE);
	 
    while (getline(send_data, MAXLINE))//输入缓冲区接收一行数据 
    {
        // 结束
        if (*send_data == 'Q' || *send_data == 'q')
        {
            puts("退出"); 
            return 0; // 正常退出
        }
        // 发送数据
        res = sendto(sock_conn, send_data, (int)strlen(send_data), 0, (SOCKADDR *)server_addr, addr_len);
        if (res == SOCKET_ERROR)
        {
        	printf("发送失败:%d\n",WSAGetLastError());
            return -1;
        }
		printf("发送数据:%s\n",send_data); 
        // 接收数据
        res = recvfrom(sock_conn, recv_data, MAXLINE, 0, NULL, NULL);
        if (res > 0)
        {
        	printf("接收到的数据:%s\n",recv_data);
        }
        else
        {
            printf("接收失败:%d\n",WSAGetLastError());
            break;
        }

        // 清空缓存
        memset(recv_data, 0, MAXLINE);
        memset(send_data, 0, MAXLINE);
    }
    return res;
}
int main()
{
    int res = -1;
    SOCKET sock_conn;
    struct sockaddr_in server_addr;
    char server_ip[] = "10.236.10.200";
    res = StartUp();//初始化动态连接库 
    if (res == -1) return -1;

    sock_conn = udpClientInit(server_ip, SEVER_PORT, server_addr, true);//连接初始化 
    if (sock_conn == -1) return -1;
	puts("连接服务器成功");
    res = udpEchoClient(sock_conn, (SOCKADDR *)&server_addr, sizeof(sockaddr_in));
    if (res == -1)puts("Error");
    closeConn(sock_conn); 
    return res;
}

循环服务器端代码

//回射程序,服务器段端,循环服务器 
#define NETWORK1_2_1_A_COMM_H
#define NETWORK1_2_1_A_COMM_H
#include 
#include 
#include 
#include 
#include 
#include 
#pragma comment(lib, "ws2_32.lib")
#define MAXLINE 4096     // 接收缓冲区长度
#define LISTENQ 1024     // 监听队列长度
#define SEVER_PORT 13442 // 端口 
/*套接字初始化*/ 
int StartUp()
{
    WORD w_version = MAKEWORD(2, 2);
    WSADATA wsa_data;
    int res = WSAStartup(w_version, &wsa_data);
    if (res != 0)
    {
    	printf("WSAStartup Error:%d\n",WSAGetLastError());
        return -1;
    }//版本号错误 
    if (LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2)
    {
       	printf("WSAStartup Error:%d\n",WSAGetLastError());
        WSACleanup();
        return -1;
    }

    return 0; //成功返回0 
}
/*释放资源*/ 
int cleanUp()
{
    int res = WSACleanup();
    if (res == SOCKET_ERROR)
    {
    	printf("WSACleanup Error:%d",WSAGetLastError()); 
        return -1;
    }
    return 0;
}
/*断开连接,释放资源*/ 
int closeConn(SOCKET sock_conn)
{
    int res = closesocket(sock_conn); //关闭连接
    if (res == SOCKET_ERROR)
    {
    	printf("关闭连接失败%d\n",WSAGetLastError());
        return -1;
    }
    res = cleanUp();
    return res;
}
/*服务器初始化*/ 
SOCKET udpServerInit(int port)
{
    int res = -1;
    SOCKET sock_listen;
    const int on = 1;

    // 绑定地址、端口
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(port);

    //创建监听套接字
    sock_listen = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_listen == INVALID_SOCKET)
    {
    	
       	printf("WSAStartup Error:%d\n",WSAGetLastError());
       	cleanUp();
        return -1;
    }

    //绑定服务器地址
    res = bind(sock_listen, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (res == SOCKET_ERROR)
    {
    	printf("绑定失败:%d\n",WSAGetLastError());
        closeConn(sock_listen);
        return -1;
    }

    return sock_listen;
}
/*循环服务器接收程序*/ 
int udpEchoServer(SOCKET sock_conn)
{
    // 此处利用指针的移动 实现添加Echo
    int res = -1;
    char recv_data[MAXLINE];
    struct sockaddr_in client_addr;
    int addr_len = sizeof(client_addr);

    do
    {
        // 清空缓存
        memset(recv_data, 0, MAXLINE);

        // 循环接收数据
        res = recvfrom(sock_conn, recv_data , MAXLINE , 0, (SOCKADDR *)&client_addr, &addr_len);
        if (res > 0)
        {
			printf("从客户端接受到数据:%s:\n",recv_data);
            // 回射接收的数据
            res = sendto(sock_conn, recv_data, res , 0, (SOCKADDR *)&client_addr, addr_len);
            if (res == SOCKET_ERROR)
            {
            	printf("sendto error:%d\n",WSAGetLastError()); 
                res = -1;
            }
            else
            {
            	printf("服务器回射数据:%s\n",recv_data);
            }
        }
        else
        {
            printf("recvfrom error:%d\n",WSAGetLastError()); 
            res = -1;
        }
    } while (res > 0);

    return res;
}
int main(int argc, char *argv[])
{
    int res = -1;
    SOCKET sock_listen;
    res = StartUp();//初始化 
    if (res == -1) return -1;//初始化失败 
    sock_listen = udpServerInit(SEVER_PORT);//创建监听套接字 
    if (sock_listen == -1) return -1;
	puts("udpServerInit success") ;
	//循环服务器 
    while (1)
    {
        // 回射 如果出错,继续其他客户端请求
        res = udpEchoServer(sock_listen);
        if (res == -1) puts("cilent connectione error,continue to connect to the next client"); 
    }
    closeConn(sock_listen); // 关闭监听服务
    return 0;
}

并发服务器端代码

#define NETWORK1_2_1_A_COMM_H
#define NETWORK1_2_1_A_COMM_H
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#pragma comment(lib, "ws2_32.lib")
#define MAXLINE 4096     // 接收缓冲区长度
#define LISTENQ 1024     // 监听队列长度
#define SEVER_PORT 13442 // 端口 
/*套接字初始化*/ 
int StartUp()
{
    WORD w_version = MAKEWORD(2, 2);
    WSADATA wsa_data;
    int res = WSAStartup(w_version, &wsa_data);
    if (res != 0)
    {
    	printf("WSAStartup Error:%d\n",WSAGetLastError());
        return -1;
    }//版本号错误 
    if (LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2)
    {
       	printf("WSAStartup Error:%d\n",WSAGetLastError());
        WSACleanup();
        return -1;
    }

    return 0; //成功返回0 
}
/*释放资源*/ 
int cleanUp()
{
    int res = WSACleanup();
    if (res == SOCKET_ERROR)
    {
    	printf("WSACleanup Error:%d",WSAGetLastError()); 
        return -1;
    }
    return 0;
}
/*断开连接,释放资源*/ 
int closeConn(SOCKET sock_conn)
{
    int res = closesocket(sock_conn); //关闭连接
    if (res == SOCKET_ERROR)
    {
    	printf("关闭连接失败%d\n",WSAGetLastError());
        return -1;
    }
    res = cleanUp();
    return res;
}
/*服务器初始化*/ 
SOCKET udpServerInit(int port)
{
    int res = -1;
    SOCKET sock_listen;
    const int on = 1;

    // 绑定地址、端口
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(port);

    //创建监听套接字
    sock_listen = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_listen == INVALID_SOCKET)
    {
    	
       	printf("WSAStartup Error:%d\n",WSAGetLastError());
       	cleanUp();
        return -1;
    }

    //绑定服务器地址
    res = bind(sock_listen, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (res == SOCKET_ERROR)
    {
    	printf("绑定失败:%d\n",WSAGetLastError());
        closeConn(sock_listen);
        return -1;
    }

    return sock_listen;
}
/*子线程,线程函数*/
void* ThreadUdpEchoServer(LPVOID pParam){
    // 此处利用指针的移动 实现添加Echo
    int sock_res;
    char recv_data[MAXLINE];
    struct sockaddr_in client_addr;
    int addr_len = sizeof(client_addr);
    // 将输入参数转换成连接套接字
    SOCKET sock_conn = *((SOCKET *) pParam);
    do {
        memset(recv_data, 0, MAXLINE);
        // 接收数据
        sock_res = recvfrom(sock_conn, recv_data, MAXLINE, 0, (SOCKADDR *) &client_addr, &addr_len);
        if (sock_res > 0) {
			printf("从客户端接收到的数据:%s\n",recv_data);
            // 回射接收的数据
            sock_res = sendto(sock_conn, recv_data, sock_res, 0, (SOCKADDR *) &client_addr, addr_len);
            if (sock_res == SOCKET_ERROR) {
				printf("sendto error:%d\n",WSAGetLastError());
                sock_res = -1;
            } else {
				printf("发送出的数据:%s\n",recv_data);
				}
        } else {
			printf("recvfrom error:%d\n",WSAGetLastError());
            sock_res = -1;
        }
    } while (sock_res > 0);

    // 出错,继续其他客户端请求
    if (sock_res == -1) puts("此用户连接出错,继续下一个连接...");
    return NULL;
}
/*并发服务器*/
int UdpServer(SOCKET sock_conn){
    int sock_res;
    char recv_data[MAXLINE];
    struct sockaddr_in client_addr;
    int addr_len = sizeof(client_addr);
    SOCKET sock_child;
    struct sockaddr_in server_addr;
    const int on = 1;
    HANDLE hThread;

    do {
        memset(recv_data, 0, MAXLINE);
        // 接收数据
        sock_res = recvfrom(sock_conn, recv_data, MAXLINE, 0, (SOCKADDR *) &client_addr, &addr_len);
        if (sock_res > 0) {
			printf("接收到的数据:%s\n",recv_data);
            // 回射接收的数据

            // 创建一个新的socket
            // 设置地址、端口
            memset(&server_addr, 0, sizeof(server_addr));
            server_addr.sin_family = AF_INET;
            server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
            server_addr.sin_port = 0;
            //创建套接字
            sock_child = socket(AF_INET, SOCK_DGRAM, 0);
            // 创建失败
            if (sock_child == INVALID_SOCKET) {
				printf("sock_child error:%d\n",WSAGetLastError());
                cleanUp();
                return -1;
            }
            
            //绑定服务器地址
            sock_res = bind(sock_child, (struct sockaddr *) &server_addr, sizeof(server_addr));
            if (sock_res == SOCKET_ERROR) {
                printf("bind error:%d\n",WSAGetLastError());
                closeConn(sock_child);
                return -1;
            }

            // 获取端口号
            struct sockaddr_in temp_conn;
            int temp_len = sizeof(temp_conn);
            sock_res = getsockname(sock_child, (SOCKADDR*)&temp_conn, &temp_len);
            if (sock_res != 0){
                puts("getsockname error");
                return -1;
            }
            int port = ntohs(temp_conn.sin_port);
            memset(recv_data, 0, MAXLINE);
            itoa(port, recv_data, 10);

            sock_res = sendto(sock_conn, recv_data, (int)strlen(recv_data), 0, (SOCKADDR *) &client_addr, addr_len);
            if (sock_res == SOCKET_ERROR) {
                printf("sendto error:%d\n",WSAGetLastError());
                sock_res = -1;
            } else {
				printf("发送出的数据:%s\n",recv_data);
				hThread=CreateThread(NULL,0,ThreadUdpEchoServer,&sock_child,0,NULL);
                return 0;
            }
        } else {
			printf("recvfrom error:%d\n",WSAGetLastError());
            sock_res = -1;
        }
    } while (sock_res > 0);

    // 出错,继续其他客户端请求
    if (sock_res == -1) 
	{
		CloseHandle(hThread);
		puts("此用户连接出错,继续下一个连接...");
	}
    return 0;
}
int main(int argc, char *argv[]) {
    int sock_res;
    SOCKET sock_listen;
	HANDLE hThread;

    if (StartUp() == -1) return -1;  // 启动
    sock_listen = udpServerInit(SEVER_PORT);  //监听
    if (sock_listen == -1) return -1;
	puts("udpServerInit success");
    while (1) {
        sock_res = UdpServer(sock_listen);
        // 出错,继续其他客户端请求
        if (sock_res == -1) puts("此用户连接出错,继续下一个连接...");
    }
	CloseHandle(hThread);
    // 关闭监听服务
    closeConn(sock_listen);
    return 0;
}

客户端代码(并发服务器对应的)

//回射程序,并发服务器对应的客户端
#define NETWORK1_2_1_A_COMM_H
#define NETWORK1_2_1_A_COMM_H
#include 
#include 
#include 
#include 
#include 
#include 
#pragma comment(lib, "ws2_32.lib")
#define MAXLINE 4096     // 接收缓冲区长度
#define LISTENQ 1024     // 监听队列长度
#define SEVER_PORT 13442 // 端口 
char server_ip[] = "10.236.10.200"; 
/*套接字初始化*/ 
int StartUp()
{
    WORD w_version = MAKEWORD(2, 2);
    WSADATA wsa_data;
    int res = WSAStartup(w_version, &wsa_data);
    if (res != 0)
    {
    	printf("WSAStartup Error:%d\n",WSAGetLastError());
        return -1;
    }//版本号错误 
    if (LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2)
    {
       	printf("WSAStartup Error:%d\n",WSAGetLastError());
        WSACleanup();
        return -1;
    }

    return 0; //成功返回0 
}
/*释放资源*/ 
int cleanUp()
{
    int res = WSACleanup();
    if (res == SOCKET_ERROR)
    {
    	printf("WSACleanup Error:%d",WSAGetLastError()); 
        return -1;
    }
    return 0;
}
/*断开连接,释放资源*/ 
int closeConn(SOCKET sock_conn)
{
    int res = closesocket(sock_conn); //关闭连接
    if (res == SOCKET_ERROR)
    {
    	printf("关闭连接失败%d\n",WSAGetLastError());
        return -1;
    }
    res = cleanUp();
    return res;
}
int getline(char s[],int lim)
{
    int c,i;
    i=0;
    while((c=getchar())!=EOF&&c!='\n'&&i<lim-1)
        s[i++]=c;
    s[i]='\0';
    return i;
}
/*回射客户端发送接收程序*/
int udpEchoClient(SOCKET sock_conn, SOCKADDR *server_addr, int addr_len)
{
    int res = -1;
    char send_data[MAXLINE], recv_data[MAXLINE];
    memset(send_data, 0, MAXLINE);
    memset(recv_data, 0, MAXLINE);
	 
    while (getline(send_data, MAXLINE))//输入缓冲区接收一行数据 
    {
        // 结束
        if (*send_data == 'Q' || *send_data == 'q')
        {
            puts("退出"); 
            return 0; // 正常退出
        }
        // 发送数据
        res = sendto(sock_conn, send_data, (int)strlen(send_data), 0, (SOCKADDR *)server_addr, addr_len);
        if (res == SOCKET_ERROR)
        {
        	printf("发送失败:%d\n",WSAGetLastError());
            return -1;
        }
		printf("发送数据:%s\n",send_data); 
        // 接收数据
        res = recvfrom(sock_conn, recv_data, MAXLINE, 0, NULL, NULL);
        if (res > 0)
        {
        	printf("接收到的数据:%s\n",recv_data);
        }
        else
        {
            printf("接收失败:%d\n",WSAGetLastError());
            break;
        }

        // 清空缓存
        memset(recv_data, 0, MAXLINE);
        memset(send_data, 0, MAXLINE);
    }
    return res;
}
/*连接服务器并绑定*/
SOCKET udpClientInit(char *server_ip, u_short port, sockaddr_in &server_addr, bool flag)
{
    int res = -1;
    SOCKET sock_conn;
    // 绑定地址、端口
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr.S_un.S_addr = inet_addr(server_ip);
    //创建套接字
    sock_conn = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock_conn == INVALID_SOCKET)
    {
    	printf("连接初始化失败%d\n",WSAGetLastError());
        cleanUp();
        return -1;
    }

    if (flag)
    {
        // 请求连接服务器
        res = connect(sock_conn, (struct sockaddr *)&server_addr, sizeof(server_addr));
        if (res == SOCKET_ERROR)
        {
            // 连接服务器失败
            printf("连接失败:%d\n",WSAGetLastError()); 
            closeConn(sock_conn);
            return -1;
        }
    }

    return sock_conn; //连接成功
}

/*对应并发服务器,客户端请求新端口函数*/
int UdpClientAskNewPort(SOCKET sock_conn, sockaddr_in server_addr, int addr_len){
    int sock_res;
    char send_data[MAXLINE] = "ASK port", recv_data[MAXLINE];
    memset(recv_data, 0, MAXLINE);

    while (1) {
        sock_res = sendto(sock_conn, send_data, (int) strlen(send_data), 0, (SOCKADDR *)&server_addr, addr_len);
        if (sock_res == SOCKET_ERROR) {
			printf("ASK port send error:%d\n",WSAGetLastError());
            return -1;
        }

        memset(recv_data, 0, MAXLINE);
        sock_res = recvfrom(sock_conn, recv_data, MAXLINE, 0, NULL, NULL);

        if (sock_res > 0) {
			printf("Requset :接收到的新端口号为:%s\n",recv_data);
			//客户端重新连接
            sock_conn = udpClientInit(server_ip, (u_short) atoi(recv_data), server_addr, true);
            if (sock_conn == -1) 
			{
				puts("客户端重新连接新端口失败");
				return -1;
			}
            sock_res = udpEchoClient(sock_conn, (SOCKADDR *)&server_addr, addr_len);
            if (sock_res == -1) puts("客户端连接失败");
            closeConn(sock_conn);

            break;
        } else {
			printf("recv error:%d\n",WSAGetLastError());
            return -1;
        }
    }

    return 0;
}

int main() {
    int sock_res;
    SOCKET sock_conn;
    sockaddr_in server_addr;
    
    if (StartUp() == -1) return -1;  // 启动
    sock_conn = udpClientInit(server_ip, SEVER_PORT, server_addr, true);  //连接
    if (sock_conn == -1) return -1;
    // 连接服务器成功
	puts("客户端启动");
    sock_res = UdpClientAskNewPort(sock_conn, server_addr, sizeof(sockaddr_in));
    if (sock_res == -1) puts("连接失败");
    closeConn(sock_conn);
    return sock_res;
}

三、用户使用说明(输入 / 输出规定)

对回射服务器和客户端(循环服务器以及并发服务器):

  1. 对于服务器端程序,用户无需输入,服务器端程序会自动输出接收到的数据以及每次发送给客户端的数据,若函数调用出现错误,会显示文字(例如:“连接失败”)并显示 WSAGetLastError()返回的错误号。
  2. 对于客户端程序,运行后当显示“连接服务器成功”后,用户可输入发给服务器的内容,回车就会发送,当输入“Q”或“q”时会断开连接。
  3. 对客户端程序,每当发送完数据后,屏幕会显示从服务器端接收到的数据

四、运行结果

回射程序,客户端和循环服务器运行结果

基于数据报套接字的服务器回射程序设计:分别以循环服务器和并发服务器实现_第4张图片

回射程序,客户端和并发服务器运行结果

基于数据报套接字的服务器回射程序设计:分别以循环服务器和并发服务器实现_第5张图片

你可能感兴趣的:(计算机网络实验,计算机网络)