图解TCP/udp及socket

TCP/IPTransmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。
UDPUser Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。
        协议的关系图

                                                                                

                                                                       

       TCP/IP协议族包括运输层、网络层、链路层。现在你知道TCP/IPUDP的关系了吧。


Socket是什么呢?
       Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

      

       先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
  

服务器端的代码为

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <sys/socket.h>  
  4. #include <netinet/in.h>  
  5. #include <stdlib.h>  
  6. #include <syslog.h>  
  7. #include <errno.h>  
  8. #define MAX_LISTEN_NUM 5  
  9. #define SEND_BUF_SIZE 100  
  10. #define RECV_BUF_SIZE 100  
  11. #define LISTEN_PORT 1010  
  12. int main()  
  13. {  
  14.   int listen_sock = 0;  
  15.   int app_sock = 0;  
  16.   struct sockaddr_in hostaddr;  
  17.   struct sockaddr_in clientaddr;  
  18.   int socklen = sizeof(clientaddr);  
  19.   char sendbuf[SEND_BUF_SIZE] = {0};  
  20.   char recvbuf[RECV_BUF_SIZE] = {0};  
  21.   int sendlen = 0;  
  22.   int recvlen = 0;  
  23.   int retlen = 0;  
  24.   int leftlen = 0;  
  25.   char *ptr = NULL;  
  26.   memset((void *)&hostaddr, 0, sizeof(hostaddr));  
  27.   memset((void *)&clientaddr, 0, sizeof(clientaddr));  
  28.   hostaddr.sin_family = AF_INET;  
  29.   hostaddr.sin_port = htons(LISTEN_PORT);  
  30.   hostaddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  31.   listen_sock = socket(AF_INET, SOCK_STREAM, 0);  
  32.   if(listen_sock < 0)  
  33.   {  
  34.       syslog(LOG_ERR, "%s:%d, create socket failed", __FILE__, __LINE__);  
  35.       exit(1);  
  36.   }  
  37.   if(bind(listen_sock, (struct sockaddr *)&hostaddr, sizeof(hostaddr)) < 0)  
  38.   {  
  39.       syslog(LOG_ERR, "%s:%d, bind socket failed", __FILE__, __LINE__);  
  40.       exit(1);  
  41.   }  
  42.   if(listen(listen_sock, MAX_LISTEN_NUM) < 0)  
  43.   {  
  44.       syslog(LOG_ERR, "%s:%d, listen failed", __FILE__, __LINE__);  
  45.       exit(1);  
  46.   }  
  47.   while(1)  
  48.   {  
  49.       app_sock = accept(listen_sock, (struct sockaddr *)&clientaddr, &socklen);  
  50.       if(app_sock < 0)  
  51.      {  
  52.         syslog(LOG_ERR, "%s:%d, accept failed", __FILE__, __LINE__);  
  53.         exit(1);  
  54.      }  
  55.      sprintf(sendbuf, "welcome %s:%d here!/n", inet_ntoa(clientaddr.sin_addr.s_addr), clientaddr.sin_port);  
  56.      //send data  
  57.      sendlen = strlen(sendbuf) +1;  
  58.      retlen = 0;  
  59.      leftlen = sendlen;  
  60.      ptr = sendbuf;  
  61.      //while(leftlen)  
  62.      {  
  63.          retlen = send(app_sock, ptr, sendlen, 0);  
  64.       if(retlen < 0)  
  65.       {  
  66.           if(errno == EINTR)  
  67.             retlen = 0;  
  68.         else  
  69.             exit(1);  
  70.       }  
  71.       leftlen -= retlen;  
  72.       ptr += retlen;  
  73.      }  
  74.      //receive data  
  75.      recvlen = 0;  
  76.      retlen = 0;  
  77.      ptr = recvbuf;  
  78.      leftlen = RECV_BUF_SIZE -1;  
  79.      //do  
  80.      {  
  81.          retlen = recv(app_sock, ptr, leftlen, 0) ;  
  82.       if(retlen < 0)  
  83.       {  
  84.           if(errno == EINTR)  
  85.             retlen = 0;  
  86.         else  
  87.             exit(1);  
  88.       }  
  89.       recvlen += retlen;  
  90.       leftlen -= retlen;  
  91.       ptr += retlen;  
  92.      }  
  93.      //while(recvlen && leftlen);  
  94.      printf("receive data is : %s", recvbuf);  
  95.     close(app_sock);  
  96.   }  
  97.   close(listen_sock);  
  98.     
  99.   return 0;  
  100.     
  101.     
  102. }  

 

 

客户端代码为:

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <sys/socket.h>  
  4. #include <netinet/in.h>  
  5. #include <syslog.h>  
  6. #include <errno.h>  
  7. #include <stdlib.h>  
  8. #define MAX_LISTEN_NUM 5  
  9. #define SEND_BUF_SIZE 100  
  10. #define RECV_BUF_SIZE 100  
  11. #define SERVER_PORT 1010  
  12. int main()  
  13. {  
  14.     int sock_fd = 0;  
  15.     char recvbuf[RECV_BUF_SIZE] = {0};  
  16.     char sendbuf[SEND_BUF_SIZE] = {0};  
  17.     int recvlen = 0;  
  18.     int retlen = 0;  
  19.     int sendlen = 0;  
  20.     int leftlen = 0;  
  21.     char *ptr = NULL;  
  22.     struct sockaddr_in ser_addr;  
  23.       
  24.     memset(&ser_addr, 0, sizeof(ser_addr));  
  25.     ser_addr.sin_family = AF_INET;  
  26.     inet_aton("127.0.0.1", (struct in_addr *)&ser_addr.sin_addr);  
  27.     ser_addr.sin_port = htons(SERVER_PORT);  
  28.     sock_fd = socket(AF_INET, SOCK_STREAM, 0);  
  29.     if(sock_fd < 0)  
  30.     {  
  31.         syslog(LOG_ERR, "%s:%d, create socket failed", __FILE__, __LINE__);  
  32.         exit(1);  
  33.     }  
  34.     if(connect(sock_fd, (struct sockaddr *)&ser_addr, sizeof(ser_addr)) < 0)  
  35.     {  
  36.         syslog(LOG_ERR, "%s:%d, connect socket failed", __FILE__, __LINE__);  
  37.         exit(1);  
  38.     }  
  39.      //receive data  
  40.      recvlen = 0;  
  41.      retlen = 0;  
  42.      ptr = recvbuf;  
  43.      leftlen = RECV_BUF_SIZE -1;  
  44.      //do  
  45.      {  
  46.          retlen = recv(sock_fd, ptr, leftlen, 0) ;  
  47.       if(retlen < 0)  
  48.       {  
  49.           if(errno == EINTR)  
  50.             retlen = 0;  
  51.         else  
  52.             exit(1);  
  53.       }  
  54.       recvlen += retlen;  
  55.       leftlen -= retlen;  
  56.       ptr += retlen;  
  57.      }  
  58.      //while(recvlen && leftlen);  
  59.      printf("receive data is : %s", recvbuf);  
  60.      sprintf(sendbuf, "hello server/n");  
  61.      //send data  
  62.      sendlen = strlen(sendbuf) +1;  
  63.      retlen = 0;  
  64.      leftlen = sendlen;  
  65.      ptr = sendbuf;  
  66.     // while(leftlen)  
  67.      {  
  68.          retlen = send(sock_fd, ptr, sendlen, 0);  
  69.       if(retlen < 0)  
  70.       {  
  71.           if(errno == EINTR)  
  72.             retlen = 0;  
  73.         else  
  74.             exit(1);  
  75.       }  
  76.       leftlen -= retlen;  
  77.       ptr += retlen;  
  78.      }  
  79.      close(sock_fd);  
  80.       
  81. }  


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值