1、 实验目的:在linux系统下进行网络c语言编程,学习并熟悉使用vim编辑器、gcc编译以及gdb调试,了解网络编程的原理,掌握网络编程中常用的函数。
在一个终端中(服务器端)运行 $ ./ server
显示为:

此时,屏幕上首先打印出明文、暗文对照表,服务器正在等待连接请求。
在另一个终端(客户端)运行 $ ./client localhost
显示为:

同样,屏幕上首先打印出明文、暗文对照表,并显示就绪。
服务器端上显示:

服务器端连接成功,可以开始聊天通信。
(1)服务器端发送消息 客户端接收消息

(2)客户端发送消息 服务器端接收消息

udp-client.c
2、 实验内容: 密文通信
实验共有2个部分,一个是服务器程序udp-server.c,另一个是客户机程序udp-client.c。实验基本思想,通信双方可以互发信息,但所发的内容在网络中是以暗文的形式传送的;双发各持有暗明文对照表,当将暗文接受完成后,又自动将暗文转换成明文形式显示在屏幕上,从而实现了双方间简单的秘密通信,信息传输过程中,即使所发送的数据包被截取,其他人也不能获取准确的信息。在一个终端中(服务器端)运行 $ ./ server
显示为:

此时,屏幕上首先打印出明文、暗文对照表,服务器正在等待连接请求。
在另一个终端(客户端)运行 $ ./client localhost
显示为:

同样,屏幕上首先打印出明文、暗文对照表,并显示就绪。
服务器端上显示:

服务器端连接成功,可以开始聊天通信。
(1)服务器端发送消息 客户端接收消息

(2)客户端发送消息 服务器端接收消息

3、 源程序及注释
udp-server.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#define MAXBUF 1024
#define MYPORT 3490
#define BACKLOG 10
int main(int argc, char **argv)
{
int sockfd, new_fd;
socklen_t len;
struct sockaddr_in my_addr, their_addr;
char buf[MAXBUF + 1],buf1[MAXBUF+1];
fd_set rfds;
struct timeval tv;
int retval, maxfd = -1;
int i,j,m,n,p,q;
//定义并打印明文、暗文对照表
char mid1[]={32,'a','s','d','f','g','h','j','k','l','\n'};
char mid2[]={'0','1','2','3','4','5','6','7','8','9','\n'};
printf("明文、暗文对照表:\n");
for(i=0;i<=10;i++){ printf("%3c",mid1[i]); }
for(j=0;j<=11;j++){ printf("%3c",mid2[j]); }
//创建一个套接字
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
else printf("socket created\n");
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MYPORT);
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
//把自己绑在一个地址上
if (bind(sockfd, (struct sockaddr *)
&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
else printf("binded\n");
//侦听连接
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
else printf("begin listen\n");
while (1) {
len = sizeof(struct sockaddr);
//接受引入的请求
if ((new_fd =accept(sockfd, (struct sockaddr *) &their_addr,&len)) == -1) {
perror("accept");
continue;
}
printf("server:got connect from %s\n", inet_ntoa(their_addr.sin_addr));
printf ("\n准备就绪\n");
while(1) {
FD_ZERO(&rfds); //清除文件描述符集
FD_SET(0, &rfds);
maxfd = 0;
FD_SET(new_fd, &rfds); //把当前连接添加到文件描述符集
if (new_fd > maxfd)
maxfd = new_fd;
//开始等待
tv.tv_sec = 1;
tv.tv_usec = 0;
retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);
if (retval == -1) {
printf("将退出,select出错! %s", strerror(errno));
break;
}
else {
if (FD_ISSET(0, &rfds)) { // 读取用户内容发送
bzero(buf, MAXBUF+1);
bzero(buf1,MAXBUF+1);
fgets(buf, MAXBUF, stdin);
//将buf明文转变问buf1暗文发送
for(m=0;m<=strlen(buf);m++)
{ for(n=0;n<=9;n++)
{ if(buf[m]==mid1[n])
buf1[m]=mid2[n];
}
}
len=send(new_fd, buf1, strlen(buf1), 0);
if (len > 0)
printf ("暗文:%s\t发送成功\n", buf1);
else {
printf ("暗文:%s\t发送失败\n", buf1);
break;
}
}
}
if (FD_ISSET(new_fd, &rfds)) { // 接受对方的消息内容
bzero(buf, MAXBUF + 1);
bzero(buf1,MAXBUF+1);
len=recv(new_fd, buf, MAXBUF, 0);
//将buf暗文转变问buf1明文并显示
for(p=0;p<=strlen(buf);p++)
{ for(q=0;q<=9;q++)
{ if(buf[p]==mid2[q])
buf1[p]=mid1[q];
}
}
if (len > 0){
printf ("\n暗文:%s\t接受成功\n", buf);
printf("明文:%s\n",buf1); }
else {
printf ("\n接受失败\n");
break;
}
}
}
}
close(sockfd);
return 0;
}
udp-client.c
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netdb.h>
#define MAXBUF 1024
#define PORT 3490
int main(int argc, char **argv)
{
int sockfd;
struct hostent *he;
struct sockaddr_in their_addr;
socklen_t len;
char buf[MAXBUF + 1],buf1[MAXBUF+1];
fd_set rfds;
struct timeval tv;
int retval, maxfd = -1;
int i,j,m,n,p,q;
if(argc!=2){
fprintf(stderr,"usage:client hostname\n");
exit(1);
}
//获取主机信息
if((he=gethostbyname(argv[1]))==NULL){
herror("gethostbyname");
exit(1);
}
//创建一个套接字
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("socket");
exit(1);
}
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(PORT);
their_addr.sin_addr =* ((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero),8);
//连接服务器
if (connect(sockfd, (struct sockaddr *) &their_addr,
sizeof(their_addr)) == -1) {
perror("connect ");
exit(1);
}
//定义并打印明文、暗文对照表
char mid1[]={32,'a','s','d','f','g','h','j','k','l','\n'};
char mid2[]={'0','1','2','3','4','5','6','7','8','9','\n'};
printf("明文、暗文对照表:\n");
for(i=0;i<=10;i++){ printf("%3c",mid1[i]); }
for(j=0;j<=11;j++){ printf("%3c",mid2[j]); }
printf("准备就绪\n");
while (1) {
FD_ZERO(&rfds); //清除文件描述符集
FD_SET(0, &rfds);
maxfd = 0;
FD_SET(sockfd, &rfds); //把当前连接添加到文件描述符集
if (sockfd > maxfd)
maxfd = sockfd;
//开始等待
tv.tv_sec = 1;
tv.tv_usec = 0;
retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);
if (retval == -1) {
printf("将退出,select出错! %s", strerror(errno));
break;
}
else {
if (FD_ISSET(sockfd, &rfds)) { // 接受对方的消息内容
bzero(buf, MAXBUF + 1);
bzero(buf1,MAXBUF+1);
len=recv(sockfd, buf, MAXBUF, 0);
//将buf暗文转变问buf1明文并显示
for(m=0;m<=strlen(buf);m++)
{ for(n=0;n<=9;n++)
{ if(buf[m]==mid2[n])
buf1[m]=mid1[n];
}
}
if (len > 0){
printf ("\n暗文:%s\t接受成功\n", buf);
printf("明文:%s\n",buf1); }
else {
printf ("\n接受失败\n");
break;
}
}
}
if (FD_ISSET(0, &rfds)) { // 读取用户内容发送
bzero(buf, MAXBUF+1);
bzero(buf1,MAXBUF+1);
fgets(buf, MAXBUF, stdin);
//将buf明文转变问buf1暗文发送
for(p=0;p<=strlen(buf);p++)
{ for(q=0;q<=9;q++)
{ if(buf[p]==mid1[q])
buf1[p]=mid2[q];
}
}
len=send(sockfd, buf1, strlen(buf1), 0);
if (len > 0)
printf ("暗文:%s\t发送成功\n", buf1);
else {
printf ("暗文:%s\t发送失败\n", buf1);
break;
}
}
}
close(sockfd);
return 0;
}

2519

被折叠的 条评论
为什么被折叠?



