Linux C 网络编程

来源:互联网 发布:2013office软件下载 编辑:程序博客网 时间:2024/05/21 17:57

经过一段时间,总结下简单练习 tcp 、 udp 通信

tcp 传输层协议通信

//tcp 协议实现 server client端的传输层信息通信//server = socket描述符  bind绑定ip+端口号  listen打开端口   accpet阻塞等待client连接//client = socket描述符  connect连接serverip+端口号//server client 使用send recv 通信//tcp 通信   server端while不断开  client能不断连接#include "func.h"int main(int argc,char* argv[]){    int sfd;    sfd=socket(AF_INET,SOCK_STREAM,0);    struct sockaddr_in ser;    memset(&ser,0,sizeof(ser));    ser.sin_family=AF_INET;    ser.sin_port=htons(atoi(argv[2]));    ser.sin_addr.s_addr=inet_addr(argv[1]);    int ret;    ret=bind(sfd,(struct sockaddr*)&ser,sizeof(ser));    listen(sfd,10);  //端口就打开了    int new_fd=-1;    struct sockaddr_in cli;    int len=sizeof(cli);    char buf[128]={0};    fd_set rdset;    fd_set tmpset;    //客户端交互new_fd socket 记录被监控的描述符    FD_ZERO(&tmpset);    FD_SET(0,&tmpset);   //监控stdin、sfd 两个描述符    FD_SET(sfd,&tmpset);    while(1){             FD_ZERO(&rdset);        //第一次进入while循环时,只会进入sfd,&redset判断内部        memcpy(&rdset,&tmpset,sizeof(fd_set));           ret=select(11,&rdset,NULL,NULL,NULL);        if(FD_ISSET(sfd,&rdset)){           new_fd=accept(sfd,(struct sockaddr*)&cli,&len);           FD_SET(new_fd,&tmpset);           printf("client addr=%s,client port=%d\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port));        }        if(FD_ISSET(new_fd,&rdset)){   //第一次 new_fd不在rdset中           memset(buf,0,sizeof(buf));           ret=recv(new_fd,buf,sizeof(buf),0);   //recv会阻塞           if(ret>0){                      printf("client:%s\n",buf);            }else if(ret==0){             printf("bye bye\n");             close(new_fd);             FD_CLR(new_fd,&tmpset);             }        }        if(FD_ISSET(0,&rdset)&&FD_ISSET(new_fd,&tmpset)){    //new_fd不存在时会崩溃            memset(buf,0,sizeof(buf));            ret=read(0,buf,sizeof(buf));            if(ret>0){                send(new_fd,buf,strlen(buf)-1,0);            }else{              printf("bye bye\n");              break;            }        }    }    close(new_fd);    close(sfd);    return 0;}//client端#include "func.h"int main(int argc,char* argv[]){    int sfd;    sfd=socket(AF_INET,SOCK_STREAM,0);    struct sockaddr_in ser;    memset(&ser,0,sizeof(ser));    ser.sin_family=AF_INET;    ser.sin_port=htons(atoi(argv[2]));    ser.sin_addr.s_addr=inet_addr(argv[1]);    int ret;    ret=connect(sfd,(struct sockaddr*)&ser,sizeof(ser));    char buf[128]={0};    fd_set rdset;    while(1)    {        FD_ZERO(&rdset);        FD_SET(0,&rdset);        FD_SET(sfd,&rdset);        ret=select(sfd+1,&rdset,NULL,NULL,NULL);        if(ret>0)        {            if(FD_ISSET(sfd,&rdset))            {                memset(buf,0,sizeof(buf));                ret=recv(sfd,buf,sizeof(buf),0);//recv会阻塞                if(ret>0)                {                    printf("server:%s\n",buf);                }else if(0==ret)                {                    printf("byebye\n");                    break;                }            }            if(FD_ISSET(0,&rdset))            {                memset(buf,0,sizeof(buf));                ret=read(0,buf,sizeof(buf));                if(ret>0)                {                    ret=send(sfd,buf,strlen(buf)-1,0);                    printf("send ok\n");                }else{                    printf("byebye\n");                    break;                }            }        }    }    return 0;}

udp 传输层协议通信

//udp通信   select模型 //server只能先recivefrom client//server端#include "func.h"int main(int argc,char **argv){    int sfd;    sfd=socket(AF_INET,SOCK_DGRAM,0);    struct sockaddr_in ser;    memset(&ser,0,sizeof(ser));    ser.sin_family=AF_INET;    ser.sin_port=htons(atoi(argv[2]));    ser.sin_addr.s_addr=inet_addr(argv[1]);    int ret;    ret=bind(sfd,(struct sockaddr*)&ser,sizeof(ser));  //绑定端口  sfd+sockaddr_in    char buf[128]={0};    struct sockaddr_in cli;    memset(&cli,0,sizeof(cli));    int len=sizeof(cli);    //server只能先recvfrom 得到数据包;保存client socket    ret=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cli,&len);    printf("client addr=%s,client port=%d\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port));    fd_set rdset;    while(1){        FD_ZERO(&rdset);        FD_SET(0,&rdset);        FD_SET(sfd,&rdset);        ret=select(10,&rdset,NULL,NULL,NULL);        if(FD_ISSET(sfd,&rdset)){            memset(buf,0,sizeof(buf));            ret=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cli,&len);            if(ret>0){                printf("client: %s\n",buf);               // printf("client addr=%s,client port=%d\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port));            }else if(ret==0){                printf("bye bye\n");            }                       }        if(FD_ISSET(0,&rdset)){            memset(buf,0,sizeof(buf));            read(0,buf,sizeof(buf));   //发送到client            sendto(sfd,buf,strlen(buf)-1,0,(struct sockaddr*)&cli,len);        }    //close(sfd);  //应该永运不会改变    }    return 0;}//client端#include "func.h"int main(int argc,char* argv[]){    int sfd;    sfd=socket(AF_INET,SOCK_DGRAM,0);    struct sockaddr_in ser;    memset(&ser,0,sizeof(ser));    ser.sin_family=AF_INET;    ser.sin_port=htons(atoi(argv[2]));    ser.sin_addr.s_addr=inet_addr(argv[1]);    int ret;    int len=sizeof(ser);    //客户端先发送    ret=sendto(sfd,"connect",10,0,(struct sockaddr*)&ser,len);    char buf[128]={0};    struct sockaddr_in cli;    //用来保存recvfrom传出参数    memset(&cli,0,sizeof(cli));    fd_set rdset;    while(1){        FD_ZERO(&rdset);        FD_SET(0,&rdset);        FD_SET(sfd,&rdset);        ret=select(sfd+1,&rdset,NULL,NULL,NULL);        if(FD_ISSET(sfd,&rdset)){            memset(buf,0,sizeof(buf));            recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cli,&len);            printf("server: %s\n",buf);        }        if(FD_ISSET(0,&rdset)){            memset(buf,0,sizeof(buf));            read(0,buf,sizeof(buf));  //发送至server            sendto(sfd,buf,strlen(buf)-1,0,(struct sockaddr*)&ser,len);        }    }    close(sfd);    return 0;}
原创粉丝点击