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

linux-c-tcp服务带超时处理的c/s

阅读更多

1.server

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

server wait....

............................

server read :deepfuture.iteye.com

 

server send :hello

.....

server read :deepfuture.iteye.com

 

server send :hello

2.client
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$ 
3.source
1)server
#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;
    fd_set fdset;
    


                  
    //建立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);
           }
           printf("server wait....\n");           
           while(1){

              struct sockaddr_in clientaddress;
              int address_len;
              int client_sockfd;
              char mybuf[100];    
              char *buf="hello\n";  
              struct timeval timeout;//超时结构体
              //超时为2秒
              timeout.tv_sec=1;
              timeout.tv_usec=0;
              //设置fdset
              FD_ZERO(&fdset);//清除fdset
              FD_CLR(fd,&fdset);//清除fd的标志
              FD_SET(fd,&fdset);//设置标志
              //select
              if ((select(fd+1,&fdset,NULL,NULL,&timeout))<0){
                  perror("select error");
                  fflush(stdout);              
              }
              //等待连接,使用新的进程或线程来处理连接

              fflush(stdout);     
              address_len=sizeof(clientaddress);              
              if(FD_ISSET(fd,&fdset)){
                  //如果有连接到来
                 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     
            	 }                               
            }else{
                  printf(".");
                  fflush(stdout);
            }
       }
 }
 2) client
#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);                

 }
 
0
0
分享到:
评论

相关推荐

    linux C语言TCP/IP协议连接通讯

    总结,Linux下使用C语言进行TCP/IP通信涉及的知识点包括:socket编程接口、TCP/IP协议原理、连接建立与断开、数据传输以及错误处理。熟练掌握这些内容,能帮助开发者构建稳定、高效的网络应用程序。

    linux-socket-C-S.rar_C/S linux_linux c 串口_linux socket_linux 串口C

    本资料包“linux-socket-C-S.rar”聚焦于C/S(客户端/服务器)架构下的Linux串口和Socket编程,为开发者提供了宝贵的资源。 串口通信是一种传统的通信方式,常用于设备间的短距离通信,如调试设备、数据采集等。在...

    Linux_Tcp.rar_LINUX TCP _linux TCP_tcp linux

    本文将深入探讨Linux下的TCP编程,包括TCP套接字(socket)的工作原理、C/S架构的实现以及相关的TCP/Linux优化策略。 首先,TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。它通过三次握手建立连接,并...

    Linux系统调用-- recv/recvfrom 函数详解

    ### Linux系统调用-- recv/recvfrom 函数详解 #### 功能描述 `recv` 和 `recvfrom` 是两个用于从套接字接收数据的重要函数。`recv` 主要用于面向连接的套接字(例如TCP),而 `recvfrom` 可以用于面向连接和无连接...

    linux windows tcp通讯

    除了基本的TCP通信,我们还需要考虑错误处理、超时机制、数据编码解码(如JSON、XML或自定义协议)、安全加密(SSL/TLS)等问题。在附带的"tcp与socket通讯"文件中,可能包含了具体的代码示例和相关文档,这些资源...

    linux-socket-select-异步聊天

    ### Linux Socket Select 异步聊天实现详解 #### 标题:Linux Socket Select 异步聊天 #### 描述:本文档详细介绍了如何在 Linux 环境下利用 Socket 和 Select 实现一个基本的异步聊天系统。 #### 标签:Linux ...

    tcp-socket-file-transfer.rar_tcp socket linux

    以上代码只是一个简化的示例,实际的文件传输可能需要处理更多细节,如错误检查、超时、重试机制以及安全措施等。"sdf.txt"文件可能是用于测试传输的文件,或者包含有关网络编程的其他信息。 总的来说,TCP Socket...

    Linux操作系统集群LVS-ipvsadm命令参考

    - **设置TCP超时时间**:使用`settcp`选项设置TCP连接的超时时间。 - **设置TCP FIN超时时间**:使用`tcpfin`选项设置TCP FIN状态的超时时间。 - **设置UDP超时时间**:使用`udp`选项设置UDP连接的超时时间。 #### ...

    C语言基础面试题(08-网络编程).docx

    - TCP是面向连接的,提供可靠的数据传输服务,有顺序保证和错误校验。 - UDP是无连接的,不保证数据包的顺序和完整性,但具有更低的延迟和更高的传输效率。 3. **并发服务器设计**: - 通常使用多线程或多进程...

    Linux网络编程小例

    通过分析这个小例,初学者可以了解到如何在Linux环境中使用C语言进行TCP/IP编程,实现客户端和服务器之间的数据交互。这不仅有助于理解网络通信的基本原理,也为后续更复杂的网络应用开发打下坚实基础。

    Linux TCP网络通信两个例子

    在Linux系统中,TCP(Transmission Control Protocol)是一种广泛使用的面向连接的、可靠的传输层协议,为应用程序提供了全双工的数据通信。本篇文章将通过两个实际的例子深入探讨如何在Linux环境中进行TCP网络通信...

    Socket C++ TCP阻塞\非阻塞 服务器 客户端 开发

    ### Socket C++ TCP阻塞与非阻塞服务器客户端开发 #### 概述 本文档将详细介绍如何使用C++ Winsock库来开发TCP非阻塞服务器。通过本篇内容的学习,您将了解到设置socket函数为非阻塞模式的方法,并且能够深入了解...

    ipvsadm命令参考

    1. **添加一个使用 WLC 调度算法的 TCP 服务,并且开启会话持久性,设置超时时间为 300 秒**: ```shell ipvsadm -A -t 192.168.1.100:80 -s wlc -p 300 -M 255.255.255.0 ``` 2. **向上面定义的虚拟服务添加一...

    cmd操作命令和linux命令大全收集

    arp 查看和处理ARP缓存,ARP是名字解析的意思,负责把一个IP解析成一个物理性的MAC地址。arp -a将显示出全部信息 start 程序名或命令 /max 或/min 新开一个新窗口并最大化(最小化)运行某程序或命令 mem 查看cpu...

    TCP服务器如何使用select处理多客户连接

    在TCP网络编程中,处理多个客户连接是一项挑战。本文通过一个简化示例讲解了如何使用`select`函数在TCP服务器程序中有效地管理并发连接。`select`是操作系统提供的一种I/O多路复用机制,它允许服务器监控多个文件...

    利用tcp ip 协议扫描ftp端口

    本文将深入探讨如何利用TCP/IP协议进行FTP端口扫描,特别是在Unix和Linux操作系统下的实践应用。 首先,TCP/IP协议栈是一个四层模型,包括链路层、网络层、传输层和应用层。FTP(File Transfer Protocol)属于应用...

    linux 扫描器 linux 扫描器

    此外,更复杂的扫描器可能会包括延迟设置、超时处理、异常检测等特性,以提高扫描效率和准确性。 除了TCP扫描,还有UDP扫描,它基于用户数据报协议,是无连接的。UDP扫描通常用于探测无状态服务,如DNS或NTP。UDP...

    linux_socket_select_tcp_server_client基础知识.pdf

    本示例中,提供了两个源代码文件,`server.c` 和 `client.c`,分别代表TCP服务器和客户端,它们展示了如何使用socket API进行基本的通信。下面将详细解释这两个程序中的关键知识点。 1. **套接字创建**: - 服务器...

    C++设置超时时间的简单实现方法

    在给定的代码片段中,`SetTimeOut`函数接收一个套接字描述符`s`、一个整型超时时间`nTime`和一个布尔值`bRecv`,根据`bRecv`的值来决定是设置接收超时(`SO_RCVTIMEO`)还是发送超时(`SO_SNDTIMEO`)。函数的实现如下:...

Global site tag (gtag.js) - Google Analytics