UNP——TCP回射服务器

3 篇文章 0 订阅

非阻塞connect
server

#include <stdio.h>
#include <stdlib.h>
#include "tcpser.h"
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/select.h>
#include <errno.h>


#define LISTSIZE 50
//#define MAX(a,b)((a)>(b)? (a):(b))
#define ADDRBUFFER 50
#define RECV_BUFSIZE 1024
int main()
{
    fd_set* r_set,w_set,e_set;
    int sd,wd;
    int nsd;
    ssize_t num;
    int flag;
    char recv_buffer[RECV_BUFSIZE];
    char addr_buffer[ADDRBUFFER];
    struct sockaddr_in laddr, raddr;
    struct timeval timel;
    timel.tv_sec = 60;
    int raddr_size = sizeof(raddr);
    // fp = fopen();
    // int fd = fileno(fp);
    sd = socket(AF_INET,SOCK_STREAM,0);
    if(sd<0)
    {
        perror("socket");
        exit(1);          
    }
    if(setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag))<0)
    {
        perror("setsockopt");
        exit(1);             
    }
    laddr.sin_family = AF_INET;
    laddr.sin_port = htons(PORT);
    inet_pton(AF_INET,"0.0.0.0",(void*)&laddr.sin_addr);
    if(bind(sd,(void*)&laddr,sizeof(laddr))<0)
    {
        perror("bind");
        exit(1);
    }
    if(listen(sd,LISTSIZE)<0)
    {
        perror("listen");
        exit(1);        
    }

    while(1)
    {

        FD_ZERO(r_set);
        //FD_ZERO(w_set);
        FD_SET(sd,r_set);
        //FD_SET(fd,w_set);
        
        switch(select(sd+1,r_set,NULL,NULL,&timel))
        {   
            case 0:
            {
                fprintf(stdout,"timeout\n");
                break;
            }
            case -1:
            {
                if(errno == EINTR)
                    continue;  
                else
                {
                    perror("select");
                    break;
                } 
            }
            default:
            {
                if(FD_ISSET(sd,r_set))
                {
                    nsd = accept(sd,(void*)&raddr,(void*)&raddr_size);
                    if( nsd < 0)
                    {
                        perror("accept");
                        exit(1);
                    }    
                    inet_ntop(AF_INET,(void*)&raddr.sin_addr,addr_buffer,ADDRBUFFER);
                    printf("the client ip is %s, port is %d\n",addr_buffer,ntohs(raddr.sin_port));
                    while(1)
                    {
                        num = recv(nsd,recv_buffer,RECV_BUFSIZE,0);
                        if(num == 0)
                        {
                            printf("end \n");
                            break;
                        }
                        else if(num<0)
                        {
                            perror("recv");
                            exit(1);
                        }
                        if(write(nsd,recv_buffer,num)<0)
                        {
                            perror("write");
                            exit(1);
                        }
                    }
                    close(nsd);
                }
            }
        }

    }
    
    close(sd);
    exit(0);

}


client,connect非阻塞版本
参考非阻塞socket链接https://blog.csdn.net/u010871058/article/details/76147082

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <string.h>
#include <strings.h>
#include "tcpser.h"
#include <fcntl.h>
#include <errno.h>

#define MAXLINE 1024

int main(int argc, char* argv[])
{
    int sockfd;
    int n;
    struct sockaddr_in servaddr;
    char buf[MAXLINE];
    fd_set rset, wcoset;
    int maxfd;
    int stdineof;

    if(argc != 2){
        printf("invalid usage!\n");
        exit(1);
    }

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        perror("socket");
        exit(1);
    }

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    inet_pton(AF_INET,  argv[1], &servaddr.sin_addr);

    int fcmd = fcntl(sockfd,F_GETFL,0); //返回原来的文件标志
    fcntl(sockfd,F_SETFL,O_NONBLOCK|fcmd); //在原来的文件标志的基础上增加非阻塞标志
    
    if(connect(sockfd, (void*)&servaddr, sizeof(servaddr)) < 0){
        //perror("socket");
        if(errno == EINPROGRESS)  //非阻塞conncet在设置socket为O_NONBLOCK后,或者SOCK_NONBLOCK后,用IO复用判断
        {						//	connect非阻塞返回EINPROGRESS可能是遇到errno,或者阻塞了,需要getsockopt设置
            FD_SET(0, &wcoset);		//SOL_SOCKET level查看error,均为返回值+错误码判断!
            FD_SET(sockfd, &wcoset);
            if(select(sockfd+1,NULL,&wcoset,NULL,NULL)<0)
            {
                perror("select");
                exit(1);
            }
            if(FD_ISSET(sockfd, &wcoset))
            {
                int flag;
                socklen_t sflag = sizeof(flag);
                if(getsockopt(sockfd,SOL_SOCKET,SO_ERROR,(void*)&flag,&sflag)<0)
                {   
                    
                    printf("the error is : %s\n",strerror(flag));
                    exit(1);
                }
                printf("conncet 2 successifully\n");
            }
        }

    }
    else
    {
        printf("conncet 1 successifully\n");
    }

    maxfd = sockfd;
    FD_ZERO(&rset);
    stdineof = 0;

    while(1){
        if(stdineof == 0)
        FD_ZERO(&rset);
        FD_SET(sockfd, &rset);

        if((n = select(maxfd+1, &rset, NULL, NULL, NULL)) < 0){
            printf("select error\n");
            exit(1);
        }

        if(FD_ISSET(0, &rset)){
            if((n = read(0, buf, MAXLINE)) == 1){
                printf("shutdown ready\n");
                stdineof = 1;
                if(shutdown(sockfd, SHUT_RD) < 0){
                    perror("shutdown");
                    exit(1);
                }
                FD_CLR(0, &rset);
                continue;
            }
            else if(n < 0){
                perror("read");
                exit(1);
            }
            if((n = write(sockfd, buf, n)) < 0){
                perror("write");
                exit(1);
            }
        }

        if(FD_ISSET(sockfd, &rset)){
            if((n = read(sockfd, buf, MAXLINE)) == 0){
                if(stdineof == 1)
                    break;
                else{
                    printf("server terminated\n");
                    exit(1);
                }
            }
            else if(n < 0){
                perror("read");
                exit(1);
            }
            if((n = write(1, buf, n)) < 0){
                perror("write");
                exit(1);
            }
        }
    }
    return 0;
}

h文件

#ifndef TCPSER_H_
#define TCPSER_H_

#define PORT 2010



#endif 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值