`
deepfuture
  • 浏览: 4398192 次
  • 性别: Icon_minigender_1
  • 来自: 湛江
博客专栏
073ec2a9-85b7-3ebf-a3bb-c6361e6c6f64
SQLite源码剖析
浏览量:80056
1591c4b8-62f1-3d3e-9551-25c77465da96
WIN32汇编语言学习应用...
浏览量:70002
F5390db6-59dd-338f-ba18-4e93943ff06a
神奇的perl
浏览量:103302
Dac44363-8a80-3836-99aa-f7b7780fa6e2
lucene等搜索引擎解析...
浏览量:285642
Ec49a563-4109-3c69-9c83-8f6d068ba113
深入lucene3.5源码...
浏览量:15001
9b99bfc2-19c2-3346-9100-7f8879c731ce
VB.NET并行与分布式编...
浏览量:67503
B1db2af3-06b3-35bb-ac08-59ff2d1324b4
silverlight 5...
浏览量:32103
4a56b548-ab3d-35af-a984-e0781d142c23
算法下午茶系列
浏览量:45965
社区版块
存档分类
最新评论

linux-网络编程-TCP多进程C/S

阅读更多

 

开2个终端窗口:

1)

deepfuture@deepfuture-laptop:~/private/mytest$ ./testtcpc

client send....

client send :deepfuture.iteye.com

 

client read :hello

 

deepfuture@deepfuture-laptop:~/private/mytest$ ./testtcpc

client send....

client send :deepfuture.iteye.com

 

client read :hello

 

deepfuture@deepfuture-laptop:~/private/mytest$ 


2)
deepfuture@deepfuture-laptop:~/private/mytest$ ./testtcps
server wait....
server wait....

server read :deepfuture.iteye.com

server send :hello
server wait....

server read :deepfuture.iteye.com

server send :hello
二、客户端

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
//deepfuture.iteye.com
ssize_t readn(int fd,void *ptr,size_t maxcn){//读取n个字符,maxc为读取的数目
    size_t noreadcn,readcn;
    char *buf=ptr;
    
    
    noreadcn=maxcn;
    while(noreadcn>0){
       if ( (readcn=read(fd,buf,noreadcn))<0){//读数据
    
          if (errno==EINTR) {//数据读取前,操作被信号中断 deepfuture.iteye.com
             perror("中断错误");
             readcn=0;            
          }
          else {return -1;}//无法修复错误,返回读取失败
       }
       else if(readcn==0) break;//EOF deepfuture.iteye.com
           
       noreadcn-=readcn;//读取成功,但是如果读取的字符数小于maxc,则继续读,因为可能数据还会继续通过网络送过来    
       buf+=readcn;   
        if (*buf==0) break;    //如果读到字符串结尾标志则退出,必须有这句,否则会死循环  deepfuture.iteye.com
       }   

    return (maxcn-noreadcn);
}

ssize_t writen(int fd,void *ptr,size_t maxcn){//写入n个字符
    size_t nowritecn,writecn;
    char *buf=ptr;
    
    nowritecn=maxcn;
    while(nowritecn>0){
       if((writecn=write(fd,buf,nowritecn))<=0){//写数据
          if (errno==EINTR) {//数据写前,操作被信号中断
             perror("中断错误");
             writecn=0;             
          }
          else {return -1;}//无法修复错误,返回读取失败
       }
    
       nowritecn-=writecn;
       buf+=writecn; 

       }  
       return (maxcn-nowritecn);
}

int main(void){
    int fd;
    int addresslen;
    struct sockaddr_in address;//地址信息结构 deepfuture.iteye.com
    int pid;
    char mybuf[100];        
    char *buf="deepfuture.iteye.com\n";
    int rc;


    fd=socket(AF_INET,SOCK_STREAM,0);//建立socket
    if (fd==-1){//错误,类型从errno获得
        perror("error");//perror先输出参数,后跟":"加空格,然后是errno值对应的错误信息(不是错误代码),最后是一个换行符。    deepfuture.iteye.com     
    }
  
    printf("client send....\n");
    fflush(stdout);
    
    //连接
    address.sin_family=AF_INET;//IPV4协议,AF_INET6是IPV6 deepfuture.iteye.com
    address.sin_addr.s_addr=inet_addr("127.0.0.1");//l表示32位,htonl能保证在不同CPU的相同字节序
    address.sin_port=htons(1253);//端口号,s表示16位 deepfuture.iteye.com
    addresslen=sizeof(address);        
    rc=connect(fd,(struct sockaddr *)&address,addresslen);//连接服务器 deepfuture.iteye.com
    if (rc==-1){//rc=0成功,rc=-1失败 deepfuture.iteye.com
      perror("连接错误");
      exit(1);
    }
    //发送数据 
    writen(fd,(void *)buf,strlen(buf)+1);
    printf("client send :%s\n",buf);      
    //读取数据
    bzero(mybuf,100);  
    readn(fd,(void *)mybuf,100); 
    printf("client read :%s\n",mybuf); 
    close(fd);
    exit(0);                

 }
 服务端
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
//deepfuture.iteye.com
ssize_t readn(int fd,void *ptr,size_t maxcn){//读取n个字符,maxc为读取的数目
    size_t noreadcn,readcn;
    char *buf=ptr;

    
    
    noreadcn=maxcn;
    while(noreadcn>0){
       if ( (readcn=read(fd,buf,noreadcn))<0){//读数据
    
          if (errno==EINTR) {//数据读取前,操作被信号中断
             perror("中断错误");
             readcn=0;           
          }
          else {return -1;}//无法修复错误,返回读取失败
       }
       else if(readcn==0) break;//EOF
       
       
       noreadcn-=readcn;//读取成功,但是如果读取的字符数小于maxc,则继续读,因为可能数据还会继续通过网络送过来    
       buf+=readcn;  
       if (*buf==0) break;//如果读到字符串结尾标志则退出,必须有这句,否则会死循环
       }  


     
    return (maxcn-noreadcn);
}

ssize_t  writen(int fd,void *ptr,size_t maxcn){//写入n个字符
    size_t nowritecn,writecn;
    char *buf=ptr;

    
    nowritecn=maxcn;
    while(nowritecn>0){
       if((writecn=write(fd,buf,nowritecn))<=0){//写数据
       
          if (errno==EINTR) {//数据写前,操作被信号中断
             perror("中断错误");
             writecn=0;             
          }
          else {return -1;}//无法修复错误,返回读取失败
       }

      
       nowritecn-=writecn;
       buf+=writecn;  

       } 

       return (maxcn-nowritecn);
}

int main(void){
    int fd;
    int addresslen;
    struct sockaddr_in address;//地址信息结构
    int pid;
    int rc;


                  
    //建立socket
    fd=socket(AF_INET,SOCK_STREAM,0);//fd为socket
    if (fd==-1){//错误,类型从errno获得
        perror("error");//perror先输出参数,后跟":"加空格,然后是errno值对应的错误信息(不是错误代码),最后是一个换行符。        
    }
    
    //bind 到socket fd    
    address.sin_family=AF_INET;//IPV4协议,AF_INET6是IPV6
    address.sin_addr.s_addr=htonl(INADDR_ANY);//l表示32位,htonl能保证在不同CPU的相同字节序
    address.sin_port=htons(1253);//端口号,s表示16位
    addresslen=sizeof(address);
    

    bind(fd,(struct sockaddr *)&address,addresslen);//bind
    
           //建立socket队列,指定最大可接受连接数
           rc=listen(fd,32);//最多接收32个连接,开始监听
           //int listen(int sockfd, int backlog)返回:0──成功, -1──失败
           //内核会在自己的进程空间里维护一个队列以跟踪这些完成的连接但服务器进程还没有接手处理或正在进行的连接
           if (rc==-1) {
              perror("listen error");//监听失败
              exit(1);
           }
           while(1){

              struct sockaddr_in clientaddress;
              int address_len;
              int client_sockfd;
              char mybuf[100];    
              char *buf="hello\n";              

              //等待连接,使用新的进程或线程来处理连接
              printf("server wait....\n");
              fflush(stdout);     
              address_len=sizeof(clientaddress);
              client_sockfd=accept(fd,(struct sockaddr *)&clientaddress,&address_len);//client_sockfd可理解为一个文件句柄,能用read和write操作。client_address是客户端信息结构 deepfuture.iteye.com
              
              //fork进程来处理每个客户的连接      
              pid=fork();
              if (pid<0){//错误
                printf("error:%s\n",strerror(errno));//strerror将errno映射为一个错误信息串 deepfuture.iteye.com
                close(client_sockfd);
                exit(1); 
              }   

              if (pid==0){ //子进程处理每个客户端的数据            
                  close(fd);//子进程关闭不需要它处理的监听资源

                  //读取数据 deepfuture.iteye.com
                  bzero(mybuf,100);                   
                  readn(client_sockfd,(void *)mybuf,100);
                  printf("\nserver read :%s",mybuf);                  
                   //发送数据                  
                  writen(client_sockfd,(void *)buf,strlen(buf)+1);               
                  printf("\nserver send :%s",buf);                
                  close(client_sockfd);
                  exit(0);
             }
             else {//父进程
                  close(client_sockfd);//父进程不处理客户端连接,因此关闭,但并不意味着把子进程的处理句柄关闭,因为子进程继承了父进程的client_sockfd资源         deepfuture.iteye.com     
             }
     }
 }
 

 

0
0
分享到:
评论

相关推荐

    linux C语言 网络编程教程及源码

    5、Linux网络编程05——C/S与B/S架构的区别 6、Linux网络编程06——UDP协议编程 7、Linux网络编程07——广播 8、Linux网络编程08——多播 9、Linux网络编程09——TCP编程之客户端 10、Linux网络编程10——TCP编程之...

    linux网络基础和网络编程

    Linux网络基础和网络编程是IT领域中的重要组成部分,特别是在服务器端开发中不可或缺。本文将深入探讨这个主题,从Linux网络的基础知识开始,逐步讲解到Socket编程以及如何实现高并发服务器。 1. Linux网络基础: ...

    Java网络编程--TCP网络编程(tcp缩略语)

    Java网络编程中的TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。在Java中,我们通常使用Socket类来实现TCP网络编程。Socket是Java.IO包的一部分,提供了网络通信的...

    linux编程技术-多线程-网络编程

    本资料集专注于"Linux编程技术-多线程-网络编程",它涵盖了UNIX环境高级编程、Linux网络编程、Linux多线程编程、Linux窗口编程以及Linux脚本编程等多个核心主题。这些内容都是构建高效、可靠且可扩展的Linux应用的...

    Linux-UNIX系统编程手册.pdf

    《Linux/UNIX系统编程手册》是一本旨在深入介绍Linux和UNIX系统编程接口的权威指南,该书由经验丰富的Linux编程专家Michael Kerrisk所著。 该手册详细描述了系统编程中必须掌握的系统调用和库函数。系统调用是用户...

    Linux-UNIX系统编程手册(上册)1

    《Linux-UNIX系统编程手册(上册)》是由Linux编程专家Michael Kerrisk撰写的一部权威指南,详细介绍了Linux和UNIX系统的编程接口。这本书是针对那些希望掌握系统编程技能的开发者,无论是在Linux还是其他UNIX平台上...

    Linux网络编程-网络基础-socket编程-高并发服务器.pdf

    C/S模式和B/S模式是常见的网络应用程序设计模式: - C/S模式:客户端和服务器分别部署,客户端处理用户交互,服务器处理业务逻辑。优点是性能高,可定制性强,但客户端需安装,维护成本较高。 - B/S模式:基于...

    QT_TCP.rar_C/S服务器_QT TCP_linux 网络_tcp linux QT_tcp s/c

    QT_TCP.rar 文件包含了一个基于Linux平台的C/S(客户机/服务器)架构的TCP网络通信程序,使用了QT库来实现TCP套接字的交互。QT是一个跨平台的应用开发框架,特别适合于创建图形用户界面应用程序,同时也支持非GUI...

    linux-file-transfer.zip_TCP/IP LINUX FILE_linux file transfer_li

    对于初学者,理解并实现这样一个文件传输系统可以帮助深入理解TCP/IP协议的工作原理,以及如何在Linux环境下进行网络编程。 总的来说,这个压缩包提供的资源可以帮助学习者掌握如何在Linux系统中利用TCP/IP协议实现...

    aarch64-linux-android-gdb.zip

    GDB是GNU项目的一部分,是一款强大的源代码级调试器,支持多种编程语言,包括C、C++、Objective-C、Python等。在Android开发中,GDB用于远程调试应用程序,通过与设备上的目标程序进行通信,允许开发者查看变量值、...

    linux网络编程和TCP-IP详解

    在IT领域,Linux网络编程和TCP/IP协议是网络开发的核心部分。这些概念和技术构成了互联网通信的基础,对于系统管理员、软件开发者以及任何与网络打交道的人来说都至关重要。以下是对这些主题的详细解析: 首先,...

    Linux-C语言编程系列

    总的来说,Linux下的C语言编程涵盖了操作系统原理、系统调用、文件I/O、进程和线程管理、网络编程、内存管理等多个方面。通过不断实践和学习,开发者可以利用C语言的威力,充分挖掘Linux系统的潜力,创建高效、稳定...

    基于Linux 网络编程 聊天工具

    此项目是基于Linux下的网络编程的一个扩展项目,基于网络的聊天工具,项目模块包括 Linux C 服务器, Linux C 客户端及数据库的制作。服务器采用 TCP 线并发服务器来实现多个客户端同时连接并占用服务器的情况,其中...

    linux 非堵塞tcp/server tcp/client

    在Linux系统中,非堵塞(Non-blocking)TCP编程是一种高级网络编程技术,它允许程序以异步的方式处理网络I/O操作。非堵塞模式下,当一个socket无法立即完成读写操作时,系统调用不会阻塞,而是立刻返回,使得程序...

    Linux-Unix网络编程

    7. **并发服务器设计**:讨论单线程、多线程和多进程模型在构建网络服务器时的优缺点,以及如何选择和实现合适的并发模型。 8. **错误处理和调试**:学习如何处理网络编程中常见的错误,如连接中断、超时、内存不足...

Global site tag (gtag.js) - Google Analytics