现在的位置: 首页 > 综合 > 正文

Linux下的网络编程

2013年06月30日 ⁄ 综合 ⁄ 共 4892字 ⁄ 字号 评论关闭

1、 实验目的:在linux系统下进行网络c语言编程,学习并熟悉使用vim编辑器、gcc编译以及gdb调试,了解网络编程的原理,掌握网络编程中常用的函数。

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;
}

抱歉!评论已关闭.