热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

使用C语言编写基于TCP协议的Socket通讯程序实例分享

这篇文章主要介绍了使用C语言编写基于TCP协议的Socket通讯程序实例分享,能够实现包括重新连接与每分钟通信一次等的功能,需要的朋友可以参考下

tcp客户端示例

#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
 
typedef struct _NSS_HEADER 
{ 
  unsigned short     ProtocolVersion;    /* 协议版本信息 */ 
  unsigned short     MsgType;        /* 消息类型 */ 
  unsigned short     TransactionNo;     /* 传输编号 */ 
  unsigned short     PacketLength;      /* 数据包长度,包括Header */ 
}NSS_HEADER;  
 
int str_echo(int sockfd, unsigned short no) 
{ 
  ssize_t readLen; 
  ssize_t writeLen; 
  char  buf[8]; 
 
  NSS_HEADER *hdr = (NSS_HEADER*)buf; 
  memset( hdr, 0, sizeof(NSS_HEADER) ); 
  hdr->TransactiOnNo= no; 
 
  // 写数据 
  int nWriteLen = 0; 
  while ( true ) 
  { 
    writeLen = write(sockfd, &buf[nWriteLen], sizeof(NSS_HEADER)-nWriteLen); 
//    printf( "write %d/n", writeLen); 
    
    if (writeLen <0 && errno == EINTR) 
    { 
      continue; 
    } 
    else if ( writeLen <0 ) 
    { 
      perror ( "write:" ); 
      return -1; 
    } 
 
    nWriteLen += writeLen; 
    // 已写完,直接返回 
    if (nWriteLen >= sizeof(NSS_HEADER) ) 
    { 
      break; 
    } 
  } 
 
  printf( "send data successed. trans no: %d/n", no ); 
 
  // 读数据 
  int nReadLen = 8; 
  while ( true ) 
  {     
    readLen = read(sockfd, buf, nReadLen); 
//    printf( "read: %d/n", readLen ); 
    if (readLen <0 && errno == EINTR) 
    { 
      continue; 
    } 
    else if ( readLen <= 0 ) 
    { 
      perror( "read:"); 
      return -1; 
    } 
    else  
    { 
      nReadLen -= readLen; 
      if (nReadLen <= 0 ) 
      { 
        break; 
      } 
    } 
  } 
 
  printf( "read response successed./n" ); 
 
  return 0; 
} 
 
int main(int argc, char **argv) 
{ 
  printf("client ip: %s/n", argv[1]); 
  printf("client port: %s/n", argv[2]); 
  printf("server ip: %s/n", argv[3]); 
  printf("server port: %s/n", argv[4]); 
 
  printf("/n service starting.../n/n"); 
  while( true ) 
  { 
    int   socketFd; 
    struct sockaddr_in svrAddr; 
    struct sockaddr_in localAddr; 
 
    socketFd = socket (AF_INET, SOCK_STREAM, 0); 
    if ( -1 == socketFd ) 
    { 
      perror( "socket:" ); 
      continue; 
    } 
 
    // 设置地址可复用 
    int option = 1; 
    setsockopt( socketFd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option) ); 
    // 客户端IP 
    memset(&localAddr, 0, sizeof(localAddr)); 
    localAddr.sin_family = AF_INET; 
    localAddr.sin_addr.s_addr = inet_addr( argv[1]); 
    localAddr.sin_port = htons (atoi(argv[2])); 
 
    int bindResult = bind(socketFd, (struct sockaddr *) &localAddr, sizeof(localAddr)); 
    if ( -1 == bindResult ) 
    { 
      perror( "bind:" ); 
      sleep(10); 
      close(socketFd); 
      continue; 
    } 
 
    // 服务器IP 
    memset(&svrAddr, 0, sizeof(svrAddr)); 
    svrAddr.sin_family = AF_INET; 
    svrAddr.sin_addr.s_addr = inet_addr( argv[3]); 
    svrAddr.sin_port = htons (atoi(argv[4])); 
 
    // 不断重连 
    int cOnnResult= connect(socketFd, (struct sockaddr *) &svrAddr, sizeof(svrAddr)); 
    if ( -1 == connResult ) 
    { 
      perror( "connect:" ); 
      sleep(10); 
      close(socketFd); 
      continue; 
    } 
     
    printf (" connect %s:%s successed./n", argv[3], argv[4] ); 
 
    static unsigned short no = 0; 
    // 连接成功,每分钟发送一次数据 
    for ( ; ; ) 
    { 
      if ( -1 == str_echo(socketFd, no++) ) 
      { 
        break; 
      } 
       
      sleep( 60 ); 
    } 
    close(socketFd); 
  } 
} 

tcp服务器源码示例

#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
 
struct _NSS_HEADER 
{ 
  unsigned short     ProtocolVersion;    /* 协议版本信息 */ 
  unsigned short     MsgType;        /* 消息类型 */ 
  unsigned short     TransactionNo;     /* 传输编号 */ 
  unsigned short     PacketLength;      /* 数据包长度,包括Header */ 
}NSS_HEADER;  
 
void str_echo(int sockfd) 
{ 
  ssize_t readLen; 
  ssize_t writeLen; 
  char  buf[8]; 
 
  while ( true ) 
  { 
    readLen = read(sockfd, buf, 8); 
    if (readLen <0 && errno == EINTR) 
    { 
      continue; 
    } 
    else if ( readLen <= 0 ) 
    { 
      perror( "read:"); 
      return ; 
    } 
    printf( "recv data successed. data len: %d/n", readLen ); 
 
    int nWriteLen = 0; 
    while ( true ) 
    { 
      writeLen == write(sockfd, &buf[nWriteLen], readLen-nWriteLen); 
 
      if (writeLen <0 && errno == EINTR) 
      { 
        continue; 
      } 
      else if ( writeLen <0 ) 
      { 
        perror ( "write:" ); 
        return; 
      } 
 
      nWriteLen += writeLen; 
 
      // 已写完,直接返回 
      if (nWriteLen >= readLen ) 
      { 
        break; 
      } 
    } 
 
    printf( "send data successed. data len: %d/n", readLen ); 
  } 
} 
 
int main(int argc, char **argv) 
{ 
  printf( "server ip: %s/n", argv[1] ); 
  printf( "server port: %s/n", argv[2] ); 
 
  printf( "/nservice starting ... /n/n" ); 
 
  int   listenfd, connfd; 
  pid_t  childpid; 
  socklen_t clilen; 
  struct sockaddr_in cliaddr, servaddr; 
 
  listenfd = socket (AF_INET, SOCK_STREAM, 0); 
  if ( -1 == listenfd ) 
  { 
    perror( "socket:" ); 
    exit(-1); 
  } 
 
  // 设置地址可复用 
  int option = 1; 
  setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option) ); 
 
  memset(&servaddr, 0, sizeof(servaddr)); 
  servaddr.sin_family = AF_INET; 
  servaddr.sin_addr.s_addr = inet_addr( argv[1]); 
  servaddr.sin_port = htons (atoi(argv[2])); 
 
  int bindResult = bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); 
  if ( -1 == bindResult ) 
  { 
    perror( "bind:" ); 
    exit(-1); 
  } 
 
  int listenResult = listen(listenfd, 5); 
  if ( -1 == listenResult ) 
  { 
    perror( "listen:" ); 
    exit(-1); 
  } 
 
  for ( ; ; )  
  { 
    clilen = sizeof(cliaddr); 
    cOnnfd= accept(listenfd, (struct sockaddr *) &cliaddr, &clilen); 
    if ( -1 == connfd ) 
    { 
      perror( "accept:" ); 
      continue; 
    } 
 
    printf ("accept %s successed.fd: %d/n", inet_ntoa(cliaddr.sin_addr), connfd ); 
 
    if ( (childpid = fork()) == 0)  
    { /* child process */ 
      close(listenfd);  /* close listening socket */ 
 
      str_echo(connfd);  /* process the request */ 
 
      printf ("disconnect from %d ./n", connfd );  
 
      exit (0); 
    } 
  } 
  close(connfd);     /* parent closes connected socket */ 
} 


推荐阅读
  • 本文介绍了如何使用Workman框架构建一个功能全面的即时通讯系统,该系统不仅支持一对一聊天、群组聊天,还集成了视频会议和实时音视频通话功能,同时提供了红包发送等附加功能。 ... [详细]
  • FTP作为一种传统的文件传输协议,广泛用于不同设备间的文件交换。然而,随着网络安全需求的提升及传输效率的要求,选择合适的FTP客户端变得尤为重要。本文将介绍如何利用WinSCP这款强大且安全的工具,实现两台电脑之间的文件高效传输。 ... [详细]
  • Redis中的字符串对象解析
    Redis中字符串对象的编码方式包括int、raw和embstr。当字符串对象存储的是可由long类型表示的整数时,该值会被直接存储在对象的ptr属性中,此时对象的编码被设为int。 ... [详细]
  • 本文详细介绍了在 Windows 7 上安装和配置 PHP 5.4 的 Memcached 分布式缓存系统的方法,旨在减少数据库的频繁访问,提高应用程序的响应速度。 ... [详细]
  • 深入解析轻量级数据库 SQL Server Express LocalDB
    本文详细介绍了 SQL Server Express LocalDB,这是一种轻量级的本地 T-SQL 数据库解决方案,特别适合开发环境使用。文章还探讨了 LocalDB 与其他轻量级数据库的对比,并提供了安装和连接 LocalDB 的步骤。 ... [详细]
  • 本文介绍了如何使用C# Winform开发局域网内的文件传输功能,详细描述了从用户界面到后端网络通信的具体实现。 ... [详细]
  • 本文探讨了Java中有效停止线程的多种方法,包括使用标志位、中断机制及处理阻塞I/O操作等,旨在帮助开发者避免使用已废弃的危险方法,确保线程安全和程序稳定性。 ... [详细]
  • 尤洋:夸父AI系统——大规模并行训练的深度学习解决方案
    自从AlexNet等模型在计算机视觉领域取得突破以来,深度学习技术迅速发展。近年来,随着BERT等大型模型的广泛应用,AI模型的规模持续扩大,对硬件提出了更高的要求。本文介绍了新加坡国立大学尤洋教授团队开发的夸父AI系统,旨在解决大规模模型训练中的并行计算挑战。 ... [详细]
  • 解决宝塔面板Nginx反向代理缓存问题
    本文介绍如何在宝塔控制面板中通过编辑Nginx配置文件来解决反向代理中的缓存问题,确保每次请求都能从服务器获取最新的数据。 ... [详细]
  • 本文详细解析 Skynet 的启动流程,包括配置文件的读取、环境变量的设置、主要线程的启动(如 timer、socket、monitor 和 worker 线程),以及消息队列的实现机制。 ... [详细]
  • 本文详细介绍了如何使用 Python 编程语言中的 Scapy 库执行 DNS 欺骗攻击,包括必要的软件安装、攻击流程及代码示例。 ... [详细]
  • 工作中频繁在不同Linux服务器之间切换时,频繁输入密码不仅耗时还影响效率。本文介绍如何通过设置SSH密钥认证,简化登录流程,提高工作效率。 ... [详细]
  • 解决远程桌面连接时的身份验证错误问题
    本文介绍了如何解决在尝试远程访问服务器时遇到的身份验证错误,特别是当系统提示‘要求的函数不受支持’时的具体解决步骤。通过调整Windows注册表设置,您可以轻松解决这一常见问题。 ... [详细]
  • 在日常运维中,频繁地对多台Linux服务器进行用户管理是一项耗时的任务。为了提高效率,可以通过编写Expect脚本来实现远程自动化操作,从而简化这一过程。 ... [详细]
  • Redis: 高效的键值存储系统
    Redis是一款遵循BSD许可的开源高性能键值存储系统,它不仅支持多种数据类型的存储,还提供了数据持久化和复制等功能,显著区别于其他键值缓存解决方案。 ... [详细]
author-avatar
棋牌
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有