UNIX网络编程简单练习

以下是我电某专业课作业,都比较简单,我就简单记录,写的也比较简陋。

一、

客户端:从命令行读入服务器的IP地址;并连接到服务器;

服务器端:接收客户的连接请求,并显示客户的IP地址和端口号;

客户端的代码如下:

// 客户端程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

int sockfd;
const char* ip_string = "127.0.0.1";
const int port = 65531; 
int main(){
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1){
		printf("%s\n", "套接字创建失败");
		exit(-1);
	}

	struct sockaddr_in srv_addr;
	socklen_t addrlen;
	addrlen = sizeof(srv_addr);
	memset(&srv_addr, 0, addrlen);
	srv_addr.sin_family = AF_INET;
	srv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	srv_addr.sin_port = htons(port);

	while (1){
		if (connect(sockfd, (struct sockaddr*)&srv_addr, sizeof(srv_addr))
			== -1)
		{
			printf("connect error!\n");
			sleep(1);
			continue;
		}
		else
			break;
	}		
}
服务端的代码如下:

// 服务器端程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

#define PORT 65531
#define BACKLOG 1

int main(){
	int listenfd, connectfd;
	struct sockaddr_in server, client;
	socklen_t sin_size;

	if((listenfd=socket(AF_INET, SOCK_STREAM, 0)) == -1){
		fprintf(stderr, "%s\n", "监听套接字创建失败。");
		exit(-1);
	}

	bzero(&server, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = htons(PORT);
	server.sin_addr.s_addr = inet_addr("127.0.0.1");
	if (bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1){
		fprintf(stderr, "%s\n", "bind执行失败。");
		exit(-1);
	}

	if (listen(listenfd, BACKLOG) == -1){
		fprintf(stderr, "%s\n", "监听错误");
		exit(-1);
	}

	sin_size = sizeof(client);
	while(1){
		if ((connectfd = accept(listenfd, (struct sockaddr*)&client, &sin_size)) == -1){
			fprintf(stderr, "%s\n", "accept错误");
			exit(-1);
		}
		printf("%s\n", "一个客户端连接:");
		char *ip = inet_ntoa(client.sin_addr);
		int port = ntohs(client.sin_port);
		printf("%s%s\n", "客户的IP是:", ip);
		printf("%s%d;\n", "客户的端口号是:", port);
	}
}
程序执行的效果如下图所示,先执行server,再执行client。

客户端:

从命令行读入服务器的IP地址;并连接到服务器;

循环从命令行读入一行字符串,并传递给服务器,由服务器对字符串反转,并将结果返回客户程序;

客户程序显示反转后的字符串;

服务器端:

接收客户的连接请求,并显示客户的IP地址和端口号;

接收客户传来的字符串,反转后传递给客户;

客户端的代码如下:

// 客户端程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

#define STRSIZE 2048
int sockfd;
const char* ip_string = "127.0.0.1";
const int port = 65531; 
int main(){
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1){
		printf("%s\n", "套接字创建失败");
		exit(-1);
	}

	struct sockaddr_in srv_addr;
	socklen_t addrlen;
	addrlen = sizeof(srv_addr);
	memset(&srv_addr, 0, addrlen);
	srv_addr.sin_family = AF_INET;
	srv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	srv_addr.sin_port = htons(port);

	while (1){
		if (connect(sockfd, (struct sockaddr*)&srv_addr, sizeof(srv_addr))
			== -1)
		{
			printf("connect error!\n");
			sleep(1);
			continue;
		}
		else
			break;
	}

	char in_string[2048];
	int len = 0;
	while(1){
		printf("%s\n", "请输入一个字符串:");
		scanf("%s", in_string);
		if(send(sockfd, in_string, strlen(in_string), 0) == -1){
			printf("%s\n", "发送失败");
			sleep(1);
			continue;
		}
		len = recv(sockfd, (void *)in_string, STRSIZE, 0);
		if (len == -1){
			printf("%s\n", "接收数据失败");
			exit(-1);
		}
		else{
			in_string[len] = '\0';
		}
		printf("%s\n", in_string);
	}		
}

服务端的代码如下:

// 服务器端程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

#define PORT 65531
#define BACKLOG 1
#define STRSIZE 2048

void revstring(char * str, int len){
	int start = 0;
	int end = len - 1;
	while(start != end && start <= end){
		char temp = str[start];
		str[start] = str[end];
		str[end] = temp;
		start++;
		end--;
	}

}


int main(){
	int listenfd, connectfd;
	struct sockaddr_in server, client;
	socklen_t sin_size;

	if((listenfd=socket(AF_INET, SOCK_STREAM, 0)) == -1){
		fprintf(stderr, "%s\n", "监听套接字创建失败。");
		exit(-1);
	}

	bzero(&server, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = htons(PORT);
	server.sin_addr.s_addr = inet_addr("127.0.0.1");
	if (bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1){
		fprintf(stderr, "%s\n", "bind执行失败。");
		exit(-1);
	}

	if (listen(listenfd, BACKLOG) == -1){
		fprintf(stderr, "%s\n", "监听错误");
		exit(-1);
	}

	sin_size = sizeof(client);
	char rev_str[STRSIZE];
	int len = 0;
	while(1){
		if ((connectfd = accept(listenfd, (struct sockaddr*)&client, &sin_size)) == -1){
			fprintf(stderr, "%s\n", "accept错误");
			exit(-1);
		}
		printf("%s\n", "一个客户端连接:");
		char *ip = inet_ntoa(client.sin_addr);
		int port = ntohs(client.sin_port);
		printf("%s%s\n", "客户的IP是:", ip);
		printf("%s%d;\n", "客户的端口号是:", port);

		while(1){
			len = recv(connectfd, rev_str, STRSIZE, 0);
			if (len == -1 || len == 0){
				printf("%s\n", "接收数据失败");
				exit(-1);
			}
			rev_str[len] = '\0';
			if (strcmp(rev_str, "exit") == 0){
				close(connectfd);
				continue;
			}
			printf("收到的数据是:%s\n", rev_str);
			revstring(rev_str, strlen(rev_str));
			printf("反转后的数据是:%s\n", rev_str);
			send(connectfd, rev_str, len, 0);
		}
	}
}

程序执行的截图如下图所示:


以上两个程序都比较简单,没有涉及服务器的并发,就是简单的练习一下。

三、

利用多线程技术实现如下并发网络程序,要求对上课时的实现进行完善,利用线程专用数据TSD实现。服务器和客户程序分别实现如下功能:


1、服务器等待客户连接,连接成功后显示客户地址,接着接收该客户的名字并显示,然后接收来自客户的信息(字符串),将该字符串反转,并将结果送回客户。要求服务器具有同时处理多个客户的能力。当某个客户断开连接时,打印所有该客户输入的数据。


2、客户首先与服务器连接,接着接收用户输入客户的名字,将该名字发送给服务器,然后接收用户输入的字符串,并发送给服务器,然后接收服务器返回的经处理后的字符串,并显示之。当用户输入Ctrl+D,终止连接并退出。

当用户输入Ctrl+D时,相当于EOF,所以在代码中当scanf等于EOF时,就close连接,并exit退出进程。

客户代码如下所示:

// 客户端程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

#define STRSIZE 2048
int sockfd;
const char* ip_string = "127.0.0.1";
const int port = 65531; 
int main(){
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1){
		printf("%s\n", "套接字创建失败");
		exit(-1);
	}

	struct sockaddr_in srv_addr;
	socklen_t addrlen;
	addrlen = sizeof(srv_addr);
	memset(&srv_addr, 0, addrlen);
	srv_addr.sin_family = AF_INET;

	char * server_addr = (char*) malloc(100);
	printf("%s\n", "请输入服务器端的地址:");
	scanf("%s", server_addr);
	srv_addr.sin_addr.s_addr = inet_addr(server_addr);
	srv_addr.sin_port = htons(port);

	while (1){
		if (connect(sockfd, (struct sockaddr*)&srv_addr, sizeof(srv_addr))
			== -1)
		{
			printf("connect error!\n");
			sleep(1);
			continue;
		}
		else
			break;
	}

	char in_string[2048];
	
	// 输入客户的名字
	printf("%s\n", "请输入客户的名字!");
	scanf("%s", in_string);
	if(send(sockfd, in_string, strlen(in_string), 0) == -1){
		printf("%s\n", "发送客户名字失败!");
		exit(-1);
	}

	// 客户输入字符串
	int len = 0;
	while(1){
		printf("%s\n", "请输入一个字符串:");
		if (scanf("%s", in_string) == EOF){
			close(sockfd);
			exit(0);
		}
		if(send(sockfd, in_string, strlen(in_string), 0) == -1){
			printf("%s\n", "发送失败");
			sleep(1);
			continue;
		}
		len = recv(sockfd, (void *)in_string, STRSIZE, 0);
		if (len == -1){
			printf("%s\n", "接收数据失败");
			exit(-1);
		}
		else{
			in_string[len] = '\0';
		}
		printf("%s\n", in_string);
	}		
}

在服务端中,利用线程技术来实现并发,在接收到客户的连接后,将sockaddr_in结构和连接套接字组成的结构作为参数传递给线程。在线程中接收和打印用户的信息。

revstring用来反转字符串,thr_fun是线程的执行函数。在thr_fun中,首先利用sockaddr_in结构打印客户端的ip和port信息,并将客户输入的信息存放在vector容器中,在客户退出时,即recv调用返回值小于等于0时,遍历vector容器,然后打印出用户输入的所有信息。

服务端的代码如下:

// 服务器端程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <vector>
#include <string>
#include <iostream>
#include <pthread.h>
using namespace std;

#define PORT 65531
#define BACKLOG 1
#define STRSIZE 2048

void revstring(char * str, int len){
	int start = 0;
	int end = len - 1;
	char temp;
	while(start != end && start <= end){
		temp = str[start];
		str[start] = str[end];
		str[end] = temp;
		start++;
		end--;
	}
}

// 需要传递给线程的变量
struct info_pthread{
	int connectfd;
	struct sockaddr_in client;
};

void * thr_fun(void *arg){
	struct info_pthread *struct_ptr = (struct info_pthread *)arg;
	vector<char*> fromClient;

	// 服务端打印客户的ip和端口信息
	printf("%s\n", "一个客户端连接:");
	char *ip = inet_ntoa((struct_ptr->client).sin_addr);
	int port = ntohs((struct_ptr->client).sin_port);
	printf("%s%s\n", "客户的IP是:", ip);
	printf("%s%d;\n", "客户的端口号是:", port);
	
	int connectfd = struct_ptr -> connectfd;
	char* str_rev;
	int len = 0;

	// 打印客户的名称
	str_rev = (char*)malloc(STRSIZE * sizeof(char));
	len = recv(connectfd, str_rev, STRSIZE, 0);
	if (len <= 0){
		printf("%s\n", "接收客户名称的数据失败");
		exit(-1);
	}
	*(str_rev + len) = '\0';
	printf("客户的名称是:%s\n", str_rev);
	fromClient.push_back(str_rev);

	// 循环接收客户的信息
	char * str_rev_cp;
	while(1){
		str_rev = (char*)malloc(STRSIZE * sizeof(char));
		len = recv(connectfd, str_rev, STRSIZE, 0);
		if (len <= 0){
			// 循环输出客户输入过的信息
			cout << "客户连接断开,客户输入过的信息如下:" << endl;
			for (vector<char*>::iterator it = fromClient.begin(); it != fromClient.end(); ++it){
				cout << *it << endl;
				free(*it);				
			}
			free(struct_ptr);
			return NULL;
		}

		*(str_rev + len)= '\0';
		printf("收到来自%s的数据是:%s\n",  fromClient[0], str_rev);
		fromClient.push_back(str_rev);
		str_rev_cp = (char*)malloc(sizeof(char) * strlen(str_rev) + 1);
		strcpy(str_rev_cp, str_rev);
		revstring(str_rev_cp, strlen(str_rev));
		printf("反转后发送给%s的数据是:%s\n", fromClient[0], str_rev_cp);
		send(connectfd, str_rev_cp, len, 0);
		free(str_rev_cp);
	}

}


int main(){
	int listenfd, connectfd;
	struct sockaddr_in server, client;
	socklen_t sin_size;

	if((listenfd=socket(AF_INET, SOCK_STREAM, 0)) == -1){
		fprintf(stderr, "%s\n", "监听套接字创建失败。");
		exit(-1);
	}

	bzero(&server, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = htons(PORT);
	server.sin_addr.s_addr = inet_addr("127.0.0.1");
	if (bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1){
		fprintf(stderr, "%s\n", "bind执行失败。");
		exit(-1);
	}

	if (listen(listenfd, BACKLOG) == -1){
		fprintf(stderr, "%s\n", "监听错误");
		exit(-1);
	}

	sin_size = sizeof(client);
	char rev_str[STRSIZE];
	int len = 0;
	int err;
	while(1){
		if ((connectfd = accept(listenfd, (struct sockaddr*)&client, &sin_size)) == -1){
			fprintf(stderr, "%s\n", "accept错误");
			exit(-1);
		}
		pthread_t tid;
		struct info_pthread * struct_ptr = (struct info_pthread *)malloc(sizeof(struct info_pthread));
		struct_ptr->client = client;
		struct_ptr->connectfd = connectfd;
		err = pthread_create(&tid, NULL, thr_fun, (void *)struct_ptr);
		if (err != 0){
			cout << "线程创建错误,错误代码:" << err << endl;
			exit(1);
		}
	}
}

程序执行的截图如下图所示,首先开启服务端,再开启客户端。

这里开启两个客户端程序,并如下图所示输入必要的信息和测试数据,服务端会收到来自客户端的信息,并将它反转后发送给客户。在客户端退出时,会将客户输入的数据全部输出。



服务器利用I/O复用技术,实现同时向多个客户提供服务。要求:
服务器:接收客户连接请求,并打印客户IP地址及端口号,然后接收客户发来的字符串,并打印该字符串和其来自与哪个客户。同时向客户返回该字符串。当某一客户断开连接时,要求服务器打印该客户输入的所有字符。
客户:从命令行接收服务器地址,并向服务器发起连接请求,连接成功后,从标准输入接收字符串并发送给服务器,等待服务器响应并打印接收的信息。

客户端的代码比较简单,如下所示:

// 客户端程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

#define STRSIZE 2048
int sockfd;
const char* ip_string = "127.0.0.1";
const int port = 65531; 
int main(){
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1){
		printf("%s\n", "套接字创建失败");
		exit(-1);
	}

	struct sockaddr_in srv_addr;
	socklen_t addrlen;
	addrlen = sizeof(srv_addr);
	memset(&srv_addr, 0, addrlen);
	srv_addr.sin_family = AF_INET;

	char * server_addr = (char*) malloc(100);
	printf("%s\n", "请输入服务器端的地址:");
	scanf("%s", server_addr);
	srv_addr.sin_addr.s_addr = inet_addr(server_addr);
	srv_addr.sin_port = htons(port);

	while (1){
		if (connect(sockfd, (struct sockaddr*)&srv_addr, sizeof(srv_addr))
			== -1)
		{
			printf("connect error!\n");
			sleep(1);
			continue;
		}
		else
			break;
	}

	char in_string[2048];
	// 客户输入字符串
	int len = 0;
	while(1){
		printf("%s\n", "请输入一个字符串:");
		if (scanf("%s", in_string) == EOF){
			close(sockfd);
			exit(0);
		}
		if(send(sockfd, in_string, strlen(in_string), 0) == -1){
			printf("%s\n", "发送失败");
			sleep(1);
			continue;
		}
		len = recv(sockfd, (void *)in_string, STRSIZE, 0);
		if (len == -1){
			printf("%s\n", "接收数据失败");
			exit(-1);
		}
		else{
			in_string[len] = '\0';
		}
		printf("%s\n", in_string);
	}		
}

服务端的代码如下所示:

服务端主要是用到了select系统调用来实现同时向多个用户提供服务的。

程序中使用了CLIENT结构来存储关于连接客户的一些信息,包括ip,端口,连接套接字fd,地址结构,并在CLIENT结构中使用vector容器来存放用户输入过的信息。

print_err函数封装了对出错的处理。

Close函数封装了关闭连接套接字时需要做的处理,包括打印客户连接的信息,释放客户结构CLIENT中包含的指针等。

handle_recv_msg封装了对接收到客户连接请求的处理,它通过push_back向CLIENT结构的vector容器里压入用户输入的数据,并将收到的信息再传回给客户端。

main函数首先定义了变量,然后创建监听套接字,绑定端口,再进入while循环,通过select调用来判断各个文件描述符是否可读。若可读,则select调用返回,然后再判断监听套接字是否在可读的套接字集中,如果在,则调用accept函数,接受客户,并做一定的处理;循环每个client的fd,判断它们是否是可读的连接套接字,如果是则接收它们的信息,然后调用handle_recv_msg函数来处理。

// 服务器端程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <vector>
#include <string>
#include <iostream>
#include <sys/select.h>

using namespace std;

#define PORT 65531
#define BACKLOG 1
#define STRSIZE 2048

typedef struct CLIENT{
	int fd;
	char *ip;
	struct sockaddr_in addr;
	int port;
	char *name;
	vector<char*> str_vec;
} CLIENT;

void print_client_addr(CLIENT *client){
	// 服务端打印客户的ip和端口信息
	printf("%s\n", "一个客户端连接:");
	char *ip = inet_ntoa((client->addr).sin_addr);
	int port = ntohs((client->addr).sin_port);
	printf("%s%s\n", "客户的IP是:", ip);
	printf("%s%d;\n", "客户的端口号是:", port);
	client->port = port;
	client->ip = ip;
}

void print_err(string err_info){
	cout << err_info << endl;
	exit(0);
}

void Close(CLIENT *client){
	// 释放结构中的vector
	vector<char*>::iterator it;
	cout << "客户("<< client->ip <<")的连接断开,客户输入过的信息如下:" << endl;
	for (vector<char*>::iterator it = (client->str_vec).begin(); it != (client->str_vec).end(); ++it){
		cout << *it << endl;
		free(*it);				
	}
	free(client->name);
	close(client->fd);
}

void handle_recv_msg(CLIENT *client, char *msg){
	char* m_msg = (char *)malloc(sizeof(char) * STRSIZE);
	strcpy(m_msg, msg);
	cout << "收到来自("<< (*client).ip << ":" << client->port << ")的消息:"<< msg <<endl;
	(client->str_vec).push_back(m_msg);
	send(client->fd, m_msg, strlen(m_msg), 0);
}

int main(){
	int listenfd, connectfd, sockfd, maxfd, i, maxi, nready, len;
	struct sockaddr_in server;
	socklen_t sin_size;
	fd_set readset, allset;
	CLIENT client[FD_SETSIZE];
	char recvbuf[STRSIZE];

	if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
		fprintf(stderr, "%s\n", "监听套接字创建失败。");
		exit(-1);
	}

	bzero(&server, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = htons(PORT);
	server.sin_addr.s_addr = inet_addr("127.0.0.1");
	if (bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1){
		fprintf(stderr, "%s\n", "bind执行失败。");
		exit(-1);
	}

	if (listen(listenfd, BACKLOG) == -1){
		print_err("监听错误");
	}

	maxfd = listenfd;
	sin_size = sizeof(server);
	maxi = -1;
	for (int i = 0; i < FD_SETSIZE; ++i){
		client[i].fd = -1;
	}
	FD_ZERO(&allset);
	FD_SET(listenfd, &allset);
	
	while(1){
		struct sockaddr_in addr;
		readset = allset;
		nready = select(maxfd + 1, &readset, NULL, NULL, NULL);
		if (nready == -1){
			if (errno == EINTR) // 被信号中断后恢复
				continue;
			print_err("select 系统调用出错,进程退出");
		}

		if (FD_ISSET(listenfd, &readset)){
			if ((connectfd = accept(listenfd, (struct sockaddr*)&addr, &sin_size)) == -1){
				print_err("accept错误");	
			}
			for(i = 0; i < FD_SETSIZE; ++i){
				if (client[i].fd < 0){
					client[i].fd = connectfd;
					client[i].name = (char *)malloc(sizeof(char) * STRSIZE);
					client[i].addr = addr;							
					client[i].name[0] = '\0';			
					break;
				}
			}
			if (i == FD_SETSIZE){
				printf("%s\n", "已接收较多的客户端连接!");			
			}
			FD_SET(client[i].fd, &allset);
			print_client_addr(&client[i]);
			if (connectfd > maxfd) 
				maxfd = connectfd;
			if (i > maxi)
				maxi = i;
			--nready;
			if (nready <= 0)
				continue;
		}
		for (i = 0; i <= maxi; ++i){
			if ((sockfd = client[i].fd) < 0)
				continue;
			if (FD_ISSET(sockfd, &readset)){
				len = recv(sockfd, recvbuf, STRSIZE, 0);
				if (len <= 0)
				{
					Close(&client[i]);
					FD_CLR(sockfd, &allset);
					client[i].fd = -1;
				}
				else{
					handle_recv_msg(&client[i], recvbuf);
				}
				if (--nready <= 0)
					break;
			}
		}
	}		
}
程序的执行截图如下图所示,可完成题中给出的要求。






  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、制作ramdisk,给出主次设备号,并使用df命令显示相关信息。(20分) 要求:(1) ramdisk的大小为学号的后3位*2,单位为M; (2)对文件系统采用ext2进行格式化。 2、编写一个c程序实现下面的功能:监视一个文件,如果文件被其他进程追加了内容,就把追加的内容打印出来。(15分) (1) 假定所编辑的c程序为mytail.c,使用命令行方式将该源程序编译,目标执行程序为mytail。给出具体的编译实现过程。 (2) 假定日志文件为/usr/tmp/pppd.log,给出打印追加内容的方法。 3、设用户mali记录了在Linux系统中的某些用户的月工资清单,记录在文件mylist.txt中,假定文件mylist.txt的内容如下: #================================================== # 登录名 工作证号 姓名 月份 工资 奖金 补助 扣除 总额 #--------------------------------------------------- wang 2076 wangxi 01 1782 1500 300 175 3407 liang 2074 liangyu 02 1560 1400 280 90 3150 zhang 3087 zhangdi 03 1804 1218 206 213 3015 wang 2076 wangxi 03 1832 1550 230 245 3367 wang 2076 wangxi 04 1832 1450 230 245 3267 liang 2074 liangyu 05 1660 1450 230 70 3270 zhang 3087 zhangdi 06 1700 1310 283 270 3023 #================================================== 只允许用户zhang读取行首字符为#的行和与用户zhang有关的行,与其他用户有关的行对用户zhang保密。(15分) (1) 编写相应的查询query.c,给出目标文件为query的实现方法; (2) 给出设置mylist.txt文件权限为仅对文件主具有读写权限的实现命令; (3) 给出设置query文件用户ID权限实现命令; (4) 给出用户zhang执行程序query的结果。 4、使用fork,exec以及wait函数构造简单的shell解释程序。(15分) (1) 假定所编辑的c程序为myxsh.c,使用命令行方式将该源程序编译,目标执行程序为myxsh。给出具体的编译实现过程。 (2) 假定当前目录下有文件信息如下: 文件的行大小 文件名 文件的行大小 文件名 920 auther.c 146 licp.txt 127 myxsh.c 124 fus.h 160 chap1.h 152 myxse.c 46 fsme.h 164 fsme 运行myxsh程序出现提示符=>后,分析find . -name *.[ch] -exec wc -l {} ; 执行结果。 5、对/usr目录进行压缩归档,结果文件名位myusr.tar。(10分) 要求:(1)以控制台方式运行; (2)将该任务挂起,再转后台,再转前台,查看进程的状态变迁过程。 6、编写程序实现通过Windows客户端对Linux服务器端进行相关网络信息配置。(25分) 要求:(1)新修改服务器的IP 地址的构成方式:网络号为192.168.2.0,主机号为学号的后3位-150;掩码为255.255.255.0;默认网关为:网络号与服务器相同,主机号为1,DNS202.117.96.10; (2)服务器端程序以deamon程序的方式运行,监听端口为学号的后4位; (3)客服端使用VC++,以GUI 方式完成对服务器端的IP 地址、掩码、默认网关、DNS信息配置输入; (4)服务器端接收客户端的配置信息后,使用exec 系列函数完成对IP 地址、掩码、默认网关、DNS修改,并写入相应的配置文件。结果验证:使用ifconfig检查IP地址信息配置的正确性;使用nslookup检查DNS信息的正确性。 把实现的信息结果与配置文件比较,检查其一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值