软件编程
位置:首页>> 软件编程>> C语言>> 使用C语言编写基于TCP协议的Socket通讯程序实例分享

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

作者:hncdsun  发布时间:2023-07-05 03:30:03 

标签:C语言,TCP,Socket

tcp客户端示例


#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

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 <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

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 */
}


0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com