Linux下的网络编程

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情
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;
}


Linux基础之网络编程 1)进程间通信的方式有**:管道,消息队列,共享内存,信号,信号量这么集中2)特点:依赖于linux内核,基本是通过内核来实现应用层的两个进程间的通信3)缺陷:无法多机通讯1)网络编程适用去不同的pc间的通信,可以实现多机运行地址和数据地址是指:IP地址和端口号。每台PC机连网够都有一个IP地址,那么每台联网的PC机可能跑多个服务器,然后每个服务器中对应的有很多进程。当客户端接入的时候,不知道去对接哪个服务器。那么这时端口号对应的就是每个服务器的端口。客户就可以通过端口号连接到对应的服务器了。 阅读详情

相关推荐

Linux C——网络编程

Linux C网络编程,一篇学会,内涵函数原型介绍,网络编程步骤,具体实现,常用实现

qq_55869380的博客 2116

linux系统编程+网络编程

C++静态库与动态库 黑马程序员-Linux系统编程 黑马程序员-Linux网络编程 g++编译4步骤 Build和Make意味着编译项目中所有源代码文件的代码,通常是一个递增过程,如果项目中有3个文件,只有1个文件被修改,只重新编译该文件。 Build All重新编译所有的源代码文件 g++ 编译参数 -I 指定头文件所在目录位置 -c 只做预处理,编译,汇编。得到二进制文件 -g 编译时添加调试文件,用于 gdb 调试 -Wall 显示所有警告信息 -D 向程序中“动态”注册宏定义 -l 指定动态.

肘子的博客 1330

基于STM32的多模态智能风扇控制系统设计与实现

本文详细介绍了基于STM32单片机的多模态智能风扇控制系统的设计与实现。系统集成了红外遥控、蓝牙手机控制及人体感应等多模态交互方式,通过PWM技术实现无级调速,并设计了安全优先的控制逻辑。文章从硬件选型、核心原理、软件编程到系统调试,提供了完整的实战指南,适合嵌入式开发爱好者学习与实践。

weixin_28285943的博客 220

Linux c编程之gcc

gcc是GNU工程的编译器,也是一个可执行程序。在linux平台也可以编译arm平台的可执行程序,一般用交叉编译器,如arm-xx-linux-gcc

szkbsgy的专栏 5139

LinuxC select函数小结

1、select机制是用于多路复用,什么叫复用,结合我的理解,就是在一个进程的一个线程里,能够同时去使用文件描述符(一般是socket套接字多连接) 2、用法步骤: fd_set rfds; //文件描述符集合 struct timeval tv; tv.tv_sec = 0; int ret, maxfd = -1; FD_ZERO(&amp...

Chz_1的博客 383

linux 建站命令,网络编程Linux gcc命令的具体使用

01. 命令概述gcc命令使用GNU推出的基于C/C++的编译器,是开放源代码领域应用最广泛的编译器,具有功能强大,编译代码支持性能优化等特点。gcc是GNU编译器套件(GNU Compiler Collection),它包括了C、C++、Objective-C、Fortran、Java、Ada、Go语言和D语言的前端,也包括了这些语言的库(如libstdc++、libgcj等等)。GCC的初衷是...

weixin_42509518的博客 148

细谈linux gcc的概念及其参数

经过长时间的学习linux gcc,发现要理解linux gcc也是必要的,今天小编给大家搜集了关于块设备的概念以及作用,希望大家看后会有很多收获。 1、linux gcc包含的c/c++编译器 gcc、cc、c++、g++: gcc和cc是一样的,c++和g++是一样的,一般c程序就用gcc编译,c++程序就用g++编译 2、linux gcc的基本用法 gcc test.c这

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 637

Linux网络编程

socket()函数用于创建一个新的套接字,并返回套接字的文件描述符。如果套接字创建失败,函数将返回-1。

cyz322649的博客 1291

linux 网络编程

linux系统编程-网络编程

qq_39855356的博客 5539

总结之linux网络编程

1.有一篇好的文章,对Linuxsocket编程的原理和要点说的很清楚: http://blog.csdn.net/chencheng126/article/details/44260799 2.一些windows网络编程的要点吧。包括大头序,小头序,网络字节序。一些常用的函数等。。 http://blog.csdn.net/chencheng126/article/detai

Thinking 1万+

Linux 网络编程

Linux 网络编程

aoeaoao的博客 1341

关于linux网络编程的项目,linux网络编程入门

如何学LINUX网络编程?你好,我是【小许爱答题】,很高兴为你解答。Linux网络编程一般用C语言,也用C++语言,因为有些网络编程的库是C++的,所以C/C++编程基础最起码要有;另外基础知识部分就是网络原理要学,还有Linux平台的基本编程技术(socket、文件相关的系统调用)。Linux网络编程基本上是一些编程技巧和代码库的运用以及编程经验的积累,学习到一定程度了可以试着编写一些网络服务器...

weixin_39994461的博客 842

Linux系统网络编程

网络系统编程,TCP,UDP,IP

2403_82436914的博客 1340

Linux C++网络编程

Linux C++ 网络编程(二) 前言 在上一节中以拆分的方式学习完 Linux 、C++、网络等知识后,这节会将这三个模块糅合起来,站在项目的基础上再次去学习这三个模块。 Linux 网路编程比较经典的有 Redis、Muduo、TeamTalk等开源项目。本文将以 Muduo 来介绍 网络编程的框架,学习完 Muduo 再去学习其他框架就容易许多了。注意, 文中贴的代码均为核心代码,且注释详细,认真阅读。 Linux C++ 网络编程 (一) Linux C++ 开发环境搭建 下载路径 githu

weixin_42496943的博客 865

Linux网络编程基础

Linux网络编程基础

weixin_57286892的博客 1309

windows下网络编程Linux网络编程的区别

它允许应用程序或 DLL 指定所需的 Windows 套接字版本,并检索特定 Windows 套接字实现的详细信息。Windows系统:getlasterror()/WSAGetLastError()Linux系统:fcntl() (需要包含头文件<fcntl.h>)​ 阻塞等待客户端的连接请求accept()(阻塞函数)​ 阻塞等待客户端的连接请求accept()(阻塞函数)obj.Receive()或者obj.Send()obj.Receive()或者obj.Send()

AAAA202012的博客 1477

Linux网络编程入门

(一)Linux网络编程--网络知识介绍Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户端        在网络程序中,如果一个程序主动和外面的程序通信,那么我们把这个程序称为客户端程序。 比如我们使用ftp程序从另外一        个地方获取文件的时候,是我们的ftp程序主动同

小生物语 1万+

Linux】UDP 网络编程

UDP 的使用比较格式化,首先先套接字,接着进行(一般客户端不需要绑定),然后进行,最后套接字。

2401_86449430的博客 1万+

Linux C网络编程基础

目录 Linux套接字结构定义 Linux C的网络基础操作函数 字节顺序转换函数族 IP地址转换函数族 域名转换函数 Linux网络套接字操作函数 创建套接字描述符函数 绑定套接字函数 建立连接函数 倾听套接字切换函数 接收连接函数 关闭连接函数 套接字读写函数 套接字地址获取函数 发送和接收函数 Linux套接字结构定义 Linux在头文件<sys/so...

程序人生 1万+
上一篇: Linux 内核配置和文件系统的构建
下一篇: 让写博客成为一种习惯
breezewin
博客等级 码龄16年 3粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值