使用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
投稿
猜你喜欢
- [LeetCode] 159. Longest Substring with At Most Two Distinct Characters
- google benchmark已经为我们提供了类似的功能,而且使用相当简单。具体的解释在后面,我们先来看几个例子,我们人为制造几个时间复杂
- 一、导航栏UINavigationBar1、导航栏的使用在iOS开发中,我们通常会使用导航控制器,导航控制器中封装了一个UINavigati
- 起源flutter作为一个跨平台的框架,在绘制上体现出了它跨平台的良好性能.那么,它是如何从runApp()后 绘制上屏的呢?本文将与你一起
- 一、写在前面数据结构中的队列应该是比较熟悉的了,就是先进先出,因为有序故得名队列,就如同排队嘛,在对尾插入新的节点,在对首删除节点.jdk集
- 对于大文件的处理,无论是用户端还是服务端,如果一次性进行读取发送、接收都是不可取,很容易导致内存问题。所以对于大文件上传,采用切块分段上传,
- 1、右值1.1 简介首先区分一下左右值:左值是指存储在内存中、有明确存储地址(可取地址)的数据;右值是指可以提供数据值的数据(不可取地址)如
- [LeetCode] 9. Palindrome Number 验证回文数字Determine whether an integer is
- 本文实例为大家分享了C#超市收银系统设计的具体代码,供大家参考,具体内容如下1.登录界面代码如下:using System;using Sy
- 一般而言,Android 应用在请求数据时都是以 Get 或 Post 等方式向远程服务器发起请求,那你有没有想过其实我们也可以在 Andr
- 介绍Spring Cache是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。Spring Cache提供了一
- 前言在使用Java开发接口请求中,我们需要对请求进行进行统一返回值,这时候我们自己封装一个统一的Result返回类,下面就介绍下我用的这种的
- 上篇介绍了几种图表的公共组件X、Y轴、背景Board的绘制。这章节介绍柱状图表的绘制,相对其它图表而言简单一些,这里主要介绍图表主体的绘制,
- flutter material widget组件之信息展示组件,供大家参考,具体内容如下widget分为两类:widgets librar
- 本篇给大家详细讲解了MTKAndroid平台开发流程,大致分为44个步骤,我们把每个步骤的命令详细讲解了下,一起来学习下。1.拷贝代码仓库从
- Visual Studio 2022 默认.net framework4.8,而4.6~4.7版本的.net framework可以通过方法
- 最近在研究android自定义控件属性,学到了TypedArray以及attrs。大家也可以结合《理解Android中的自定义属性》这篇文章
- 讲这个例子前,咱们先来看一个简单的程序:字符串数组实现数字转字母:#include <stdio.h>#include <
- [LeetCode] 3. Longest Substring Without Repeating Characters 最长无重复字符的子
- 概述:Flutter中常用的滑动布局 ScrollView 有 SingleChildScrollView、NestedScrollView