`
liuye066
  • 浏览: 266401 次
  • 性别: Icon_minigender_2
  • 来自: 青岛
社区版块
存档分类
最新评论

加入fork()的区别(执行结果)

阅读更多

加入fork()的区别(执行结果)

server2.c

#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc,char **argv){
  int sockfd;
  sockfd = socket(AF_INET,SOCK_STREAM,0);
  struct sockaddr_in sin;
  sin.sin_family=AF_INET;
  sin.sin_port = htons(8000);
  sin.sin_addr.s_addr = htonl(INADDR_ANY);
  //配置本地信息,使socket与本机地址及端口号绑定
  bind(sockfd,(struct sockaddr *)&sin,sizeof(sin));
  perror("bind");
  //监听并建立输入队列,限制最大请求数
  listen(sockfd,10);
  perror("listen");

  struct sockaddr_in pin;
  int address_size = sizeof(pin);
  int temp_sockfd;
  char *msg="Hello!";

  while(1){
    printf("accept……sockfd %d\n",sockfd);
    //接收连接请求,建立一个新socket
    temp_sockfd = accept(sockfd,(struct sockaddr *)&pin,&address_size);
    printf("accept……temp_sockfd %d\n",temp_sockfd);
    //在新socket上进行数据传输
    if(send(temp_sockfd,msg,strlen(msg),0)==-1){
      perror("send");
      exit(1);
    }
    //建立子进程
    if(!fork()){
       //接收客户端的信息
       char recvserver[256];
       memset(recvserver,0,256);
       printf("%s %d\n",recvserver,strlen(recvserver));
       recv(temp_sockfd,recvserver,sizeof(recvserver),0);
       printf("%s %d\n",recvserver,strlen(recvserver));
       close(temp_sockfd);
       exit(0);
   }
    close(temp_sockfd);
   }
}
    

 server3.c(不加fork)

#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc,char **argv){
  int sockfd;
  sockfd = socket(AF_INET,SOCK_STREAM,0);
  struct sockaddr_in sin;
  sin.sin_family=AF_INET;
  sin.sin_port = htons(8000);
  sin.sin_addr.s_addr = htonl(INADDR_ANY);
  bind(sockfd,(struct sockaddr *)&sin,sizeof(sin));
  perror("bind");
  listen(sockfd,10);
  perror("listen");
  struct sockaddr_in pin;
  int address_size = sizeof(pin);
  int temp_sockfd;
  char *msg="Hello!";

  while(1){
    printf("accept……sockfd %d\n",sockfd);
    temp_sockfd = accept(sockfd,(struct sockaddr *)&pin,&address_size);
    printf("accept……temp_sockfd %d\n",temp_sockfd);
    if(send(temp_sockfd,msg,strlen(msg),0)==-1){
     perror("send");
     exit(1);
    }
    
    //接收客户端的信息
    char recvserver[256];
    memset(recvserver,0,256);
     printf("%s %d\n",recvserver,strlen(recvserver));
    recv(temp_sockfd,recvserver,sizeof(recvserver),0);
   printf("%s %d\n",recvserver,strlen(recvserver));
    close(temp_sockfd);
   }
}
    

 执行结果:

[wangcm@wang socket]$ ./server3
bind: Success
listen: Success
accept……sockfd 3
accept……temp_sockfd 4
 0
server,hello!I am client! 25
accept……sockfd 3


[wangcm@wang socket]$ ./server2
bind: Success
listen: Success
accept……sockfd 3
accept……temp_sockfd 4
accept……sockfd 3
 0
server,hello!I am client! 25

 

客户端:client2.c

#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
#include <netdb.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char **argv){
 char *host_name="127.0.0.1";
 struct hostent *server_host_name;
 server_host_name=gethostbyname(host_name);
 
 int sockfd;
 //建立socket
 sockfd=socket(AF_INET,SOCK_STREAM,0);
 struct sockaddr_in pin;
 pin.sin_family=AF_INET;
 pin.sin_addr.s_addr = ((struct in_addr *)(server_host_name->h_addr))->s_addr;
 pin.sin_port=htons(8000);
 //建立连接,之前先赋值
 connect(sockfd,(struct sockaddr *)&pin,sizeof(pin));
 perror("send"); 
 char buffer[256];
 //memset()是内存赋值函数,用来给某一内存空间赋值,
 //memset(void* _dst,int val,int len),_dst是目标起始地址,val是要赋的值,len要赋值的字节数
 memset(buffer,0,256);
 printf("%s %d\n",buffer,strlen(buffer));
 //接收数据
 recv(sockfd,buffer,sizeof(buffer),0);
 printf("%s %d\n",buffer,strlen(buffer));
 
 //传输数据
 char *sendserver="server,hello!I am client!";
 if(send(sockfd,sendserver,strlen(sendserver),0)==-1){
   perror("send");
   exit(1);
 }
 close(sockfd);
}
 
分享到:
评论

相关推荐

    Java并发Fork-Join框架原理

    fork方法用于将任务拆分成小任务,并将其加入线程队列中,而join方法用于汇总每个小任务的结果。 在Java8中,Fork-Join框架还提供了对并行流(Parallel Stream)的支持。并行流是一种特殊的流,它可以自动将计算...

    php多进程框架-模拟java多线程接口simple-fork-php.zip

    SimpleFork simple-fork-php 是基于 PCNTL 扩展的进程管理包,接口类似与 Java 的 Thread 和 Runnable 为什么要写 SimpleFork 多进程程序的编写相比较多线程编写更加复杂,需要考虑进程回收、同步、互斥、...

    20231220-程鑫宇-实验1-Linux环境基础.docx

    | ./fork | 执行 fork 程序 | 三、实验要求与内容 * 虚拟化及容器技术实验要求: + 查阅资料,简要说明虚拟化技术的特点和适用范围。 + 对比 WSL 及虚拟机软件中运行 Linux 的异同。 + 查阅资料,简要说明容器...

    linux实现软中断通信和管道通信报告(含代码)

    新进程几乎与父进程完全相同,唯一的区别在于`fork()`的返回值。在父进程中,`fork()`返回子进程的进程ID,在子进程中返回0。 - 示例代码: ```c pid_t pid; if ((pid = fork()) ) { // 错误处理 } else if ...

    操作系统实验-实验1分析解析.pdf

    在这个实验中,由于没有加入任何同步机制,三个进程(父进程和两个子进程)并发执行,导致输出结果的不确定性。例如,可能会看到'bca'、'bac'、'abc'等不同的输出序列,这是因为进程的执行顺序受到操作系统调度的...

    Linux 系统调用与实例分析.pdf

    3. 内核中的函数do_fork()被执行,开始创建新进程的过程。 4. do_fork()函数会复制父进程的进程描述符和页表项,创建一个新的地址空间。 5. do_fork()函数进一步复制父进程的文件描述符和其他资源。 6. 调度器将新...

    操作系统实验报告-(7).doc

    加入`signal(SIGNAL, SIG_IGN)`和`signal(SIGQUIT, SIG_IGN)`可以忽略特定的信号,观察这将如何影响程序的执行。 5. **进程的管道通信**: 管道是实现进程间通信的一种简单方式,使用`pipe()`创建管道,两个子进程...

    操作系统实验二(进程管理系统).doc

    加入`signal(SIGINT, SIG_IGN)`和`signal(SIGQUIT, SIG_IGN)`,表示忽略这两个信号,结果是父进程不会响应这两个信号,从而不会向子进程发送信号。这展示了信号在进程间通信的作用以及如何处理信号。 4. **进程的...

    进程和程序:编写命令解释器sh

    将新进程加入进程集合。 4. 控制权返回给两个进程。 - **fork()返回值**: - 子进程中`fork()`返回0。 - 父进程中`fork()`返回子进程的PID。 - 通过返回值可以区分父进程和子进程。 #### 5. 父进程如何等待子...

    dbx User guide 中文版

    - **处理fork和exec系统调用**:处理创建新进程的系统调用。 - **处理sproc系统调用**:处理与进程组相关的系统调用。 #### 十、dbx附录 - **附录A dbx命令集**:详细介绍dbx的所有命令及其用法。 - **附录B 预定...

    操作系统实验-进程同步与互斥.pdf

    本实验的主要目的是加深对进程概念的理解,明确进程和程序的区别,学习进程创建的过程,进一步认识进程并发执行的实质,分析进程争用资源的现象,学习解决进程互斥的方法,学习解决进程同步的方法,并掌握 Linux ...

    CFS调度器(2)-源码解析.pdf

    `fair_sched_class`结构体定义了CFS调度类的各种操作,包括`enqueue_task`、`dequeue_task`、`yield_task`等,这些函数分别对应进程的加入队列、退出队列、让出CPU等行为。其中,`pick_next_task`函数是选择下一个...

    北大Nachos系统调用实习报告

    执行用户程序相关的系统调用包括 Halt、Exit、Join、Fork、Yield 等系统调用。这些系统调用可以让用户程序控制自己的执行流程,实现进程的创建、退出、加入和让出等操作。 系统调用实现 系统调用实现是通过定义...

    nginx调试方法

    具体操作是在auto/cc/conf文件中将ngx_compile_opt="-c"修改为ngx_compile_opt="-c-g",然后执行./configure --prefix=/home/yejianfeng/nginx/来配置Nginx的安装路径,并确保Makefile文件中已经正确加入了“-g”...

    零基础教你学FPGA之Verilog语法基础(中)

    两者的区别在于执行顺序,阻塞赋值中后面的语句必须等待前面的赋值完成后才能执行,而非阻塞赋值则允许并行执行,不阻塞后续语句的执行。 接着,我们来了解块语句。Verilog中有两种块语句:顺序块和并行块。顺序块...

    Nachos的线程管理模块升级

    挂起线程时,根据线程当前状态将其状态改为`STATIC_READY`或`STATIC_BLOCKED`,并将其加入挂起队列。激活线程则通过线程ID在挂起队列中查找并恢复其状态。遗憾的是,将线程实际保存到磁盘的功能未在此实验中实现。 ...

    Program-With-OpenMP

    基于线程的并行编程模型是OpenMP的核心,采用Fork-Join模型,主线程创建一组线程,这些线程在并行域内执行任务,最后所有线程重新加入主线程,结束并行执行。 在Fortran中,OpenMP程序结构通常使用`!$OMP PARALLEL`...

    Debugging with gdb.pdf

    首先,为了使用GDB调试程序,开发者需要准备编译时加入了调试信息的可执行文件。这通常意味着在编译程序时需要添加特定的编译选项,如gcc编译器中的“-g”选项。这样编译出的程序包含了源代码与机器码之间的映射信息...

    php守护进程 加linux命令nohup实现任务每秒执行一次

    它通常通过一系列的fork操作来实现与终端的脱离,并通过setsid创建一个新的会话来进一步确保其独立性。 8. PHP脚本中守护进程的简单实现:通过编写一个shell脚本,并在其中调用PHP脚本,使用循环来维持程序运行,...

Global site tag (gtag.js) - Google Analytics