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


猜你喜欢
- 本文实例讲述了java实现求两个字符串最长公共子串的方法。分享给大家供大家参考,具体如下:这个是华为OJ上的一道题目。首先,如果我们用jav
- C++中的动态数组(Dynamic Array)是指动态分配的、可以根据需求动态增长占用内存的数组。为了实现一个动态数组类的封装,我们需要考
- 一、只读自动属性(Read-only auto-properties) C# 6之前我们构建只读自动属性: public stri
- 摘要本文主要讲解mall通过整合SpringSecurity和JWT实现后台用户的登录和授权功能,同时改造Swagger-UI的配置使其可以
- 本文实例讲述了C#实现两接口中同名方法。分享给大家供大家参考。具体分析如下:对于一个类实现两个接口,而这两个接口又有同名方法,C#中的处理方
- 想必我们在做项目的时候,都会遇到服务端与客户端交互数据。一般情况下我们都会采用json格式或者xml格式,将服务端的数据转换成这两种格式之一
- 先来看我们以前利用RestTemplate发起远程调用的代码:存在下面的问题:代码可读性差,编程体验不统一参数复杂URL难以维护1. Fei
- 目录首先,写一个需求文档:一、登录界面1.界面2.登录3.退出二、开始游戏界面三、缓冲加载游戏界面四、游戏主界面五、结束界面上代码首先,写一
- 有一个比较好理解的例子,在这跟大家介绍下: 1.如果一个后花园只种蔬菜类,那么就用简单工厂就可以了.  
- 现在的模拟器的功能太强大,从蓝牙,传感器等配件到IMEI,Mac,以及手机硬件信息什么都可以模拟为了防止用户利用模拟器模仿真机进行刷单,刷流
- 很多学习Android程序设计的人都会发现每个人对代码的写法都有不同的偏好,比较明显的就是对控件响应事件的写法的不同。因此本文就把这些写法总
- 本文实例讲述了Android编程中的消息机制。分享给大家供大家参考,具体如下:在分析Android消息机制之前,我们先来看一段代码:publ
- 使用idea创建javaweb项目idea还是写框架项目比较爽,原生的javaweb项目不是特别方便,这篇文章就是记录一下创建的过程图较多注
- Java中代码的加载顺序所能了解的知识点类的依赖关系static代码块的加载时间继承类中构造器的隐式调用非static的成员变量初始化时间m
- 实现网页版的在线聊天室的方法有很多,在没有来到HTML5之前,常见的有:定时轮询、长连接+长轮询、基于第三方插件(如FLASH的Socket
- VisualVM是JDK自带的一款全能型性能监控和故障分析工具,包括对CPU使用、JVM堆内存消耗、线程、类加载的实时监控,内存dump文件
- 1.概述在本快速教程中,我们将学习如何设置Spring Security LDAP。在我们开始之前,了解一下LDAP是什么? - 它代表轻量
- 使用后台返回验证码图片,验证码存到session中后端实现校验,前端只展示验证码图片。本篇用SpringBoot Thymeleaf实现验证
- 摘要空指针异常(NullPointerException)可以说是Java程序员最容易遇到的问题了,影响说大不大,说小也不小。为了解决这个问
- 有的时候当我们使用popwindow时将当前的activity当做View传给其他fragment使用时会导致我们设置背景变暗效果失效,导致