一个简单的接收网络数据程序

本文介绍了一个简单的TCP监听服务程序,该程序使用C语言实现,在suseLinux10平台上运行。程序主要功能为创建监听端口并接收数据包,通过两个socket进行通信,包括面向套接字及面向连接套接字。
  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <memory.h>   
  4. #include <string.h>   
  5. #include <time.h>   
  6. #include <errno.h>   
  7. #include <assert.h>   
  8. #include <sys/time.h>   
  9. #include <netinet/in.h>   
  10. #include <arpa/inet.h>   
  11. #include <assert.h>   
  12.   
  13. #define   SOCKET_ERROR       -1   
  14. #define   INVALID_SOCKET     -1   
  15.   
  16. int CreateListeningSocket(const char* ip, unsigned short port, int* err_code)   
  17. {   
  18.   int on = 1;   
  19.   int ret = 0;   
  20.   int sockfd;   
  21.   struct sockaddr_in sin;   
  22.   
  23.   if(ip != NULL)
  24.   {   
  25.     sin.sin_addr.s_addr = inet_addr(ip); 
  26.     assert(sin.sin_addr.s_addr != INADDR_NONE);   
  27.   }
  28.   else
  29.   {   
  30.     sin.sin_addr.s_addr = htonl(INADDR_ANY);   
  31.   }   
  32.   
  33.   sin.sin_family = AF_INET;   
  34.   sin.sin_port = htons(port);   
  35.   
  36.   if( (sockfd=socket(AF_INET,SOCK_STREAM,0))   !=   SOCKET_ERROR &&   
  37.       (ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on))) != SOCKET_ERROR &&   
  38.       (ret = bind(sockfd,(struct sockaddr *)&sin,sizeof(sin))) != SOCKET_ERROR &&   
  39.       (ret = listen(sockfd, 5)) != SOCKET_ERROR)
  40.   {   
  41.     return sockfd;
  42.   }   
  43.   
  44.   if(ret == SOCKET_ERROR)
  45.   {   
  46.     *err_code = errno;   
  47.     if(sockfd != SOCKET_ERROR)
  48.     {   
  49.         close(sockfd);   
  50.         sockfd   =   SOCKET_ERROR;   
  51.     }   
  52.   }   
  53.   
  54.   return sockfd;   
  55. }   
  56.   
  57.   
  58. static   void   handle_client(int   cs,   const   socdaddr_in*   sinSrc)   
  59. {   
  60.     char   str[200];   
  61.     int   n;   
  62.   
  63.     n = ::recv(cs,   str,   sizeof(str),   0);     
  64.     if (n   ==   0)
  65.     {   
  66.         printf("socket   closed/n");   
  67.     }
  68.     else if(n   <   0)
  69.     {   
  70.         printf("recv   error:%s/n",   strerror(errno));   
  71.     }
  72.     else
  73.     {   //   get   data   
  74.         printf("recv:%s/n",   str);   
  75.         strcpy(str,   "hello!   I   got   it!");   
  76.         ::send(cs,   str,   strlen(str)+1,,   0);   
  77.     }   
  78. }
  79.   
  80. int main(int argc, char* argv[])   
  81. {   
  82.     DWORD err_code;   
  83.     int s;   
  84.   
  85.     unsigned short port = 3000;   
  86.     s = CreateListeningSocket(NULL, port, &err_code);   
  87.     if(s == SOCKET_ERROR)
  88.     {   
  89.         printf("CreateListeningSocket on port (%s:%u) failed->%s/n", inet_ntoa(sin.sin_addr), port, strerror(errno));   
  90.         return -1;   
  91.     }   
  92.   
  93.     //start looping server   
  94.     while(1)
  95.     {   
  96.         int cs;   
  97.         sockaddr_in sinSrc;   
  98.         socklen_t len = sizeof(sinSrc);   
  99.   
  100.         cs = accept(s, (struct sockaddr*)&sinSrc, &len);   
  101.         if(cs < 0)
  102.         {   
  103.             continue;   
  104.         }   
  105.         
  106.         //handle cs   
  107.         handle_client(cs, &sinSrc);   
  108.         close(cs);   
  109.     }   
  110.   
  111.     close(s);   
  112.     return -1;   
  113. }

这是一个简单的测试程序。

 

平台:suse Linux 10

 

功能:简历TCP网络侦听端口,接收数据包

 

总结:

1.两个socket,一个是面向套接字,即socket的返回值;一个是面向连接套接字,accept之后的返回值。

2.有人说,同一台电脑上可以在同一个端口上建立多个套接字,比如3个进程都建立了套接字,bind了同一个端口,并且处在listen状态,网络数据过来时,只能有一个socket能收到数据,待验证。

3.只有接收了tcp连接后,才能确定对方的ip和port,即从accpet的入参中得到remote ip & remote tcp port。

 

源代码:

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值