网络编程——TCP与UDP服务器、客户端的搭建

avatar
作者
筋斗云
阅读量:3

1.1UDP服务器的搭建

{ li.c                                                                                                                                                                     #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h>  #define PORT 8888 #define IP "192.168.124.34" #define ERR_MSG(msg)    {fprintf(stderr, "line:%d ", __LINE__);\                         perror(msg);\                         }  int main(int argc, const char *argv[]) {     //创建报式套接字     int sfd = socket(AF_INET, SOCK_DGRAM, 0);     if(sfd < 0)     {         ERR_MSG("socket");         return -1;     }     printf("socket create success sfd=%d\n", sfd);      //填充地址信息结构体给bind函数使用     //真实的地址信息结构体根据地址族指定 AF_INET: man 7 IP     struct sockaddr_in sin;     sin.sin_family      = AF_INET;          //必须填AF_INET;                                                                                                                 sin.sin_port        = htons(PORT);      //端口号的网络字节序,1024~49151     sin.sin_addr.s_addr = inet_addr(IP);    //本机IP,ifconfig      //绑定服务器自身的地址信息     if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)     {         ERR_MSG("bind");         return -1;     }     printf("bind success\n");      struct sockaddr_in cin;     //存储发送放的地址信息     socklen_t addrlen =sizeof(cin);      char buf[128] = "";     ssize_t res = 0;     while(1)     {         bzero(buf, sizeof(buf));         //接收数据 --->同时存储这个数据包是从哪里来的,即发送的地址         res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &addrlen);         if(res < 0)         {             ERR_MSG("recvfrom");             return -1;         }          printf("[%s:%d] : %s\n", \                 inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);          //发送数据, 谁发给我,我发还给谁         strcat(buf, "*_*");         if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, sizeof(cin)) < 0)         {             ERR_MSG("sendto");             return -1;         }         printf("sendto success\n");     }      //关闭套接字     close(sfd);      return 0; }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              

1.2UDP客户端

 #include <stdio.h>  #include <sys/types.h>  #include <sys/socket.h>  #include <arpa/inet.h>  #include <netinet/in.h>  #include <unistd.h>  #include <string.h>     #define ERR_MSG(msg) do{\      fprintf(stderr, "__%d__ ", __LINE__);\      perror(msg);\  }while(0)     #define SER_PORT 8888           //服务器绑定的端口号  #define SER_IP "192.168.124.34"  //服务器绑定的IP     int main(int argc, const char *argv[])  {      //创建报式套接字      int cfd = socket(AF_INET, SOCK_DGRAM, 0);      if(cfd < 0)      {          ERR_MSG("socket");          return -1;      }      printf("socket create success cfd=%d\n", cfd);        //填充地址信息结构体给sendto函数使用,想发给谁就填谁的地址信息      //真实的地址信息结构体根据地址族指定 AF_INET: man 7 IP      struct sockaddr_in sin;      sin.sin_family      = AF_INET;          //必须填AF_INET;      sin.sin_port        = htons(SER_PORT);      //对端绑定的端口号      sin.sin_addr.s_addr = inet_addr(SER_IP);    //对端绑定的IP         struct sockaddr_in rcvaddr;                socklen_t addrlen = sizeof(rcvaddr);         char buf[128] = "";      ssize_t res ;      while(1)      {          bzero(buf, sizeof(buf));          printf("请输入>>> ");          fgets(buf, sizeof(buf), stdin);          buf[strlen(buf)-1] = 0;             //发送数据, 主动发送给指定接收放,例如这里可以主动发给服务器          if(sendto(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)          {              ERR_MSG("sendto");              return -1;          }          printf("sendto success\n");             bzero(buf, sizeof(buf));          res = recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&rcvaddr, &addrlen);          if(res < 0)          {              ERR_MSG("recvfrom");              return -1;                                                                             }             printf("[%s:%d] : %s\n", \                  inet_ntoa(rcvaddr.sin_addr), ntohs(rcvaddr.sin_port), buf);         }         //关闭套接字      close(cfd);         return 0;  }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

UDP服务器与客户端区别不会很明显。

2.1TCP服务器

 #include <stdio.h>  #include <sys/types.h>  #include <sys/socket.h>  #include <unistd.h>  #include <arpa/inet.h>  #include <netinet/in.h>  #include <string.h>    #define PORT 8888  #define IP "192.168.124.34"  #define ERR_MSG(msg)    {fprintf(stderr, "line:%d ", __LINE__);\                          perror(msg);\                          }  int main(int argc, const char *argv[])  {      //创建流式套接字      int sfd = socket(AF_INET, SOCK_STREAM, 0);      if(sfd < 0)      {          ERR_MSG("socket");          return -1;      }      printf("流式套接字创建完毕 sfd=%d\n", sfd);        //允许端口快速被复用      int reuse = 1;      if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)      {          ERR_MSG("setsockopt");          return -1;      }      printf("允许端口快速复用成功\n");        //填充地址信息结构体,给bind使用      //真实的地址信息结构体根据地址族制定 AF_INET-->man 7 ip      struct sockaddr_in sin;      sin.sin_family      =AF_INET;      sin.sin_port        = htons(PORT);      sin.sin_addr.s_addr = inet_addr(IP);        //绑定服务器地址,必须绑定      if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)      {          ERR_MSG("bind");          return -1;      }      printf("绑定成功\n");        //将套接字设置为监听状态      if(listen(sfd, 128) < 0)      {          ERR_MSG("listen");          return -1;      }      printf("监听成功\n");        //获取连接成功的客户端信息      //生成一个新的套接字文件描述符      struct sockaddr_in cin; //存储客户端信息      socklen_t addrlen = sizeof(cin);      int newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);      if(newfd < 0)      {          ERR_MSG("accept");          return -1;      }              printf("[%s:%d] newfd=%d 客户端连接成功\n",\                      inet_ntoa(cin.sin_addr) , ntohs(cin.sin_port), newfd);      char buf[128] = "";      size_t res ;      while(1)      {          bzero(buf, sizeof(buf));          //接收          res = recv(newfd, buf,sizeof(buf), 0);          if(res < 0)          {              ERR_MSG("recv");              return -1;          }          else if(0 == res)          {              printf("[%s:%d] newfd=%d 客户端下线\n",\                      inet_ntoa(cin.sin_addr) , ntohs(cin.sin_port), newfd);              break;          }          printf("[%s:%d] newfd=%d : %s\n",\                      inet_ntoa(cin.sin_addr) , ntohs(cin.sin_port), newfd,buf);          //发送          if(send(newfd, buf, sizeof(buf), 0) < 0)          {              ERR_MSG("send");              return -1;          }          printf("发送成功\n");      }      //关闭文件描述符      if(close(sfd) < 0)      {          ERR_MSG("close");          return -1;      }      return 0;                                                                                                                                                            }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    

2.2TCP客户端

                                                                                                                  #include <stdio.h>  #include <sys/types.h>  #include <sys/socket.h>  #include <arpa/inet.h>  #include <netinet/in.h>  #include <unistd.h>  #include <string.h>     #define ERR_MSG(msg) do{\      fprintf(stderr, "__%d__ ", __LINE__);\      perror(msg);\  }while(0)     #define SER_PORT 8888           //服务器绑定的端口号  #define SER_IP "192.168.124.34"  //服务器绑定的IP     int main(int argc, const char *argv[])  {      //创建流式套接字      int cfd = socket(AF_INET, SOCK_STREAM, 0);      if(cfd < 0)      {          ERR_MSG("socket");          return -1;      }         printf("socket 创建成功  cfd=%d\n", cfd);            //允许端口快速复用      int reuse = 1;      if(setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)      {          ERR_MSG("setsockopt");          return -1;      }         printf("允许端口快速复用成功\n");          //绑定客户端的地址信息---》非必须绑定      //客户端若不绑定,则操作系统会自动给客户端绑定本机IP及随机端口          //填充服务器的地址信息结构体给connect函数使用;      //真实的地址信息结构体根据地址族指定,AF_INET:man 7 ip      struct sockaddr_in sin;      sin.sin_family      = AF_INET;              //必须填AF_INET;      sin.sin_port        = htons(SER_PORT);      //服务器绑定的端口号      sin.sin_addr.s_addr = inet_addr(SER_IP);    //服务器绑定的IP                  //连接服务器,想要连接哪个服务器就需要填充哪个服务器绑定的地址信息      if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)      {          ERR_MSG("connect");          return -1;      }         printf("连接服务器成功\n");                  char buf[128] = "";      ssize_t res = 0;      while(1)      {          bzero(buf, sizeof(buf));          printf("请输入>>> ");          fgets(buf, sizeof(buf), stdin);          buf[strlen(buf)-1] = '\0';                    //发送数据          if(send(cfd, buf, sizeof(buf), 0) < 0)          //if(write(cfd, buf, sizeof(buf)) < 0)          {              ERR_MSG("send");              return -1;          }             printf("发送成功\n");                              bzero(buf, sizeof(buf));          //接收数据           res = recv(cfd, buf, sizeof(buf), 0);                                                                                      //res = read(cfd, buf, sizeof(buf));          if(res < 0)          {              ERR_MSG("recv");              return -1;          }             else if(0 == res)          {              printf("[%s:%d] cfd=%d 服务器下线__%d__\n", \                      SER_IP, SER_PORT, cfd, __LINE__);              break;          }             printf("[%s:%d] cfd=%d :%s __%d__\n", \                  SER_IP, SER_PORT, cfd, buf, __LINE__);                 }                       //关闭套接字      close(cfd);      return 0;  }    

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!