4月9日作业

示例代码分别展示了TCP和UDP协议下,服务端如何监听和接收客户端连接,以及客户端如何连接并发送/接收数据。TCP服务端执行监听、接受连接、读写操作,客户端执行连接、读写操作。UDP服务端和客户端则通过sendto和recvfrom进行数据的双向传输。
摘要由CSDN通过智能技术生成

1、TCP

服务端:ser

  1 #include<stdio.h>
  2 #include<sys/types.h>
  3 #include<sys/socket.h>
  4 #include<netinet/in.h>
  5 #include<netinet/ip.h>
  6 #include<unistd.h>
  7 #include<string.h>
  8 #include<arpa/inet.h>
  9 
 10 #define ERR_MSG(msg) do{\
 11     fprintf(stderr,"line:%d ",__LINE__);\
 12     perror(msg);\
 13 }while(0);
 14 
 15 #define IP "192.168.2.132"      //本机IP                                                                                                                                                                                                                                                                                                                             
 16 #define PORT 6767       //端口号1024~49151
 17 
 18 int main(int argc, const char *argv[])
 19 {
 20     //创建流式套接字
 21     int sfd = socket(AF_INET,SOCK_STREAM,0);
 22     if(sfd < 0)
 23     {
 24         ERR_MSG("socket");
 25         return -1;
 26     }
 27 
 28     //允许端口快速重用
 29     int reuse = 1;
 30     if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) < 0)
 31     {
 32         ERR_MSG("setsockopt");
 33         return -1;
 34     }
 35     printf("允许端口快速重用成功\n");
 36 
 37 
 38 
 39     //填充地址信息结构体
 40     struct sockaddr_in sin;
 41     sin.sin_family      = AF_INET;       //必须填AF_INET
 42     sin.sin_port        = htons(PORT);   //端口号
 43     sin.sin_addr.s_addr = inet_addr(IP); //本机IP
 44 
 45     //将IP和端口绑定到套接字上
 46     if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
 47     {
 48         ERR_MSG("bind");
 49         return -1;
 50     }
 51     printf("bind success __%d__\n",__LINE__);
 52 
 53     //将套接字设置为被动监听状态,监听是否有客户端连接成功;
 54     if(listen(sfd,128) < 0)
 55     {
 56         ERR_MSG("listen");
 57         return -1;
 58     }
 59     printf("listen sucess __%d__\n",__LINE__);
 60 
 61     struct sockaddr_in cin;//存储连接成功的客户端地址信息
 62     socklen_t addrlen = sizeof(cin);
 63 
 64     //阻塞函数,从已完成连接的队列头中获取一个客户端信息,生成一个新的文件描述符
 65     //该文件描述符才是与客户端通信的文件描述符
 66     int newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen);
 67     if(newfd < 0)
 68     {
 69         ERR_MSG("accept");
 70         return -1;
 71     }
 72     printf("[%s:%d] newfd = %d 连接成功__%d__\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd,__LINE__);
 73 
 74     char buf[128] = "";
 75     ssize_t res = 0;
 76     while(1)
 77     {
 78         bzero(buf,sizeof(buf));
 79         //接收
 80         res  = recv(newfd,buf,sizeof(buf),0);
 81         if(res < 0)
 82         {
 83             ERR_MSG("recv");
 84             return -1;
 85         }
 86         else if(0 == res)
 87         {
 88             printf("[%s:%d] newfd=%d 客户端下线 __%d__\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd,__LINE__);
 89             break;
 90         }
 91         printf("newfd = %d:%s\n",newfd,buf);
 92 
 93         //发送
 94         strcat(buf,"*_*");
 95         if(send(newfd,buf,sizeof(buf),0) < 0)
 96         {
 97             ERR_MSG("send");
 98             return -1;
 99         }
100         printf("发送成功\n");
101     }
102 
103 
104 
105     close(newfd);
106     close(sfd);
107 
108 
109     return 0;
110 }

客户端:cli

  1 #include<stdio.h>
  2 #include<sys/types.h>
  3 #include<sys/socket.h>
  4 #include<netinet/in.h>
  5 #include<netinet/ip.h>
  6 #include<unistd.h>
  7 #include<string.h>
  8 #include<arpa/inet.h>
  9 
 10 #define ERR_MSG(msg) do{\
 11     fprintf(stderr,"line:%d ",__LINE__);\
 12     perror(msg);\
 13 }while(0);
 14 
 15 #define IP "192.168.2.132"      //本机IP                                                                                                                                                                                                                                                                                                                             
 16 #define PORT 6767       //端口号1024~49151
 17 
 18 int main(int argc, const char *argv[])
 19 {
 20     //创建流式套接字
 21     int cfd = socket(AF_INET,SOCK_STREAM,0);
 22     if(cfd < 0)
 23     {
 24         ERR_MSG("socket");
 25         return -1;
 26     }
 27 
 28     //允许端口快速重用成功
 29     //由系统自动绑定时,可以不重用
 30     int reuse = 1;
 31     if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) < 0)
 32     {
 33         ERR_MSG("setsockopt");
 34         return -1;
 35     }
 36     printf("允许端口快速重用成功\n");
 37 
 38     //绑定客户端的地址信息结构体,非必须绑定的
 39     //如果不绑定,则由操作系统自动选择一个端口号,以及本机可用IP绑定到套接字上
 40     //将IP和端口绑定到套接字上
 41     /*
 42     if(bind(cfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
 43     {
 44         ERR_MSG("bind");
 45         return -1;
 46     }
 47     printf("bind success __%d__\n",__LINE__);
 48     */
 49     //填充服务器地址信息结构体
 50     struct sockaddr_in sin;
 51     sin.sin_family      = AF_INET;       //必须填AF_INET
 52     sin.sin_port        = htons(PORT);   //端口号
 53     sin.sin_addr.s_addr = inet_addr(IP); //本机IP
 54 
 55     //连接服务器
 56     if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
 57     {
 58         ERR_MSG("connect");
 59         return -1;
 60     }
 61     printf("connect sucess __%d__\n",__LINE__);
 62 
 63     char buf[128] = "";
 64     ssize_t res = 0;
 65     while(1)
 66     {
 67         //发送
 68         bzero(buf,sizeof(buf));
 69         fscanf(stdin,"%s",buf);
 70         buf[strlen(buf)] = 0;
 71         if(send(cfd,buf,sizeof(buf),0) < 0)
 72         {
 73             ERR_MSG("send");
 74             return -1;
 75         }
 76         printf("发送成功\n");
 77 
 78         //终端输入quit后退出程序
 79         if(strcasecmp(buf,"quit") == 0)
 80             break;
 81 
 82         //接受
 83         bzero(buf,sizeof(buf));
 84         res  = recv(cfd,buf,sizeof(buf),0);
 85         if(res < 0)
 86         {
 87             ERR_MSG("recv");
 88             return -1;
 89         }
 90         else if(0 == res)
 91         {
 92             printf("cfd = %d服务器下线 __%d__\n",cfd,__LINE__);
 93             break;
 94         }
 95         printf("cfd = %d:%s\n",cfd,buf);
 96 
 97 
 98     }
 99 
100 
101 
102     close(cfd);
103 
104 
105     return 0;
106 }

2、UDP

服务端:SER

  1 #include<stdio.h>                                                                                                                                                                                                                                                                                                                                                    
  2 #include<sys/types.h>
  3 #include<sys/socket.h>
  4 #include<netinet/in.h>
  5 #include<netinet/ip.h>
  6 #include<string.h>
  7 #include<arpa/inet.h>
  8 #include<unistd.h>
  9 
 10 
 11 #define ERR_MSG(msg) do{\
 12     fprintf(stderr,"%d",__LINE__);\
 13     perror("msg");\
 14 }while(0)
 15 
 16 #define IP "192.168.0.111"
 17 #define PORT 6767
 18 
 19 int main(int argc, const char *argv[])
 20 {
 21     //创建报式套接字
 22     int sfd = socket(AF_INET,SOCK_DGRAM,0);
 23     if(sfd < 0)
 24     {
 25         ERR_MSG("socket");
 26         return -1;
 27     }
 28 
 29     //创建填充地址信息结构体
 30     struct sockaddr_in sin;
 31     sin.sin_family      = AF_INET;
 32     sin.sin_port        = htons(PORT);
 33     sin.sin_addr.s_addr = inet_addr(IP);
 34     //绑定自身服务器端的IP和端口
 35     if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
 36     {
 37         ERR_MSG("bind");
 38         return -1;
 39     }
 40 
 41     //因为要接收数据,所以要定义一个结构体用来存储客户端的信息
 42     struct sockaddr_in cin;
 43     socklen_t addrlen = sizeof(cin);
 44 
 45     char buf[128]="";
 46     ssize_t res = 0;
 47 
 48     while(1)
 49     {
 50         //接收数据
 51         bzero(buf,sizeof(buf));
 52         //继续接受数据包发送方的地址信息,给sendto使用
 53         res = recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&addrlen);
 54         if(res < 0)
 55         {
 56             ERR_MSG("recvfrom");
 57             return -1;
 58         }
 59         printf("[%s:%d]: %s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf);
 60 
 61 
 62         //发送数据
 63         strcat(buf,"*_*");
 64         if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,sizeof(cin)) < 0)
 65         {
 66             ERR_MSG("sendto");
 67             return -1;
 68         }
 69         printf("发送成功\n");
 70     }
 71 
 72     //关闭
 73     close(sfd);
 74     return 0;
 75 }
~                                                                  

客户端:CLI

  1 #include<stdio.h>                                                                                                                                                                                                                                                                                                                                                    
  2 #include<sys/types.h>
  3 #include<sys/socket.h>
  4 #include<netinet/in.h>
  5 #include<netinet/ip.h>
  6 #include<string.h>
  7 #include<arpa/inet.h>
  8 #include<unistd.h>
  9 
 10 
 11 #define ERR_MSG(msg) do{\
 12     fprintf(stderr,"%d",__LINE__);\
 13     perror("msg");\
 14 }while(0)
 15 
 16 #define SER_IP "192.168.0.111"
 17 #define SER_PORT 6767
 18 
 19 #define CLI_IP "192.168.0.111"
 20 #define CLI_PORT 7777
 21 int main(int argc, const char *argv[])
 22 {
 23     //创建报式套接字
 24     int cfd = socket(AF_INET,SOCK_DGRAM,0);
 25     if(cfd < 0)
 26     {
 27         ERR_MSG("socket");
 28         return -1;
 29     }
 30 
 31 
 32     //绑定自身服务器端的IP和端口
 33     //非必须绑定
 34     struct sockaddr_in cin;
 35     cin.sin_family      = AF_INET;
 36     cin.sin_port        = htons(CLI_PORT);
 37     cin.sin_addr.s_addr = inet_addr(CLI_IP);
 38 
 39     if(bind(cfd,(struct sockaddr*)&cin,sizeof(cin)) < 0)
 40     {
 41         ERR_MSG("bind");
 42         return -1;
 43     }
 44     printf("client bin sucess\n");
 45 
 46     //创建填充服务器地址信息结构体
 47     struct sockaddr_in sin;
 48     sin.sin_family      = AF_INET;
 49     sin.sin_port        = htons(SER_PORT);
 50     sin.sin_addr.s_addr = inet_addr(SER_IP);
 51 
 52     struct sockaddr_in rcvaddr;
 53     socklen_t addrlen = sizeof(rcvaddr);
 54 
 55     char buf[128]="";
 56     ssize_t res = 0;
 57 
 58     while(1)
 59     {
 60         bzero(buf,sizeof(buf));
 61         printf("请输入>>>");
 62         fgets(buf,sizeof(buf),stdin);
 63         buf[strlen(buf)-1] = 0;
 64 
 65 
 66         //发送数据
 67         if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin)) < 0)
 68         {
 69             ERR_MSG("sendto");
 70             return -1;
 71         }
 72         printf("发送成功\n");
 73 
 74         //接收数据
 75         bzero(buf,sizeof(buf));
 76         //继续接受数据包发送方的地址信息,给sendto使用
 77         res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&rcvaddr,&addrlen);
 78         if(res < 0)
 79         {
 80             ERR_MSG("recvfrom");
 81             return -1;
 82         }
 83         printf("[%s:%d]: %s\n",inet_ntoa(rcvaddr.sin_addr),ntohs(rcvaddr.sin_port),buf);
 84 
 85 
 86     }
 87 
 88     //关闭
 89     close(cfd);
 90     return 0;
 91 }
~                        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

malingshu404

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值