当前位置: 首页 > article >正文

C 语言实现TCP 通信,以及地址复用

服务端

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
 
 
int main()
{
	//监听套接字文件描述符
	int listenFd = -1;
	//连接套接字的文件描述符
	int connFd = -1;
	//服务器的地址结构
	struct sockaddr_in servAddr = {0};
	//客户端的地址结构
	struct sockaddr_in cliAddr = {0};
	socklen_t len = sizeof(cliAddr);
	int ret;
	char buf[100] = {0};
 
	//创建套接字
	listenFd = socket(PF_INET, SOCK_STREAM, 0);
	if(listenFd < 0)
	{
		perror("socket error!\n");
		return -1;
	}
	printf("socket ok!\n");
	//绑定ip地址和端口号
	servAddr.sin_family = PF_INET;
	servAddr.sin_port = htons(10086);
	servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	ret = bind(listenFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
	if(ret < 0)
	{
		perror("bind error!");
		close(listenFd);
		return -1;
	}
	printf("bind ok!\n");
	//创建监听队列(使得主动的套接字变成可以被连接的被动套接字)
	ret = listen(listenFd, 1);
	if(ret < 0)
	{
		perror("listen error");
		close(listenFd);
		return -1;
	}
    printf("listening....\n");
	//等待并建立连接
	connFd = accept(listenFd, (struct sockaddr *)&cliAddr, &len);
	if(connFd < 0)
	{
		perror("accept error!");
		close(listenFd);
		return -1;
	}
	printf("IP:%s,PORT:%d accept ok!\n", inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port));
	//接收消息并打印
	ret = recv(connFd, buf, sizeof(buf), 0);
	if(ret < 0)
	{
		perror("recv error!");
		close(listenFd);
		close(connFd);
		return -1;
	}
	printf("recv:%s\n", buf);
	//关闭套接字
	sleep(4);
	close(listenFd);
	close(connFd);
	return 0;
}

客户端

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
 
int main()
{
	int sockFd = -1;
	//服务器的地址结构
	struct sockaddr_in servAddr = {0};
	int ret;
	char buf[100] = "aaaaaaaaa";
 
	//创建套接字
	sockFd = socket(PF_INET, SOCK_STREAM, 0);
	if(sockFd < 0)
	{
		perror("socket error!\n");
		return -1;
	}
	printf("socket ok!\n");
	//按照服务器的ip地址和端口号连接服务器
	servAddr.sin_family = PF_INET;
	servAddr.sin_port = htons(10086);
	servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	ret = connect(sockFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
	if(ret < 0)
	{
		perror("connect error!");
		close(sockFd);
		return -1;
	}
	printf("connect ok!\n");
	//发送消息
    	ret = send(sockFd, buf, sizeof(buf), 0);
	if(ret < 0)
	{
		perror("send error!");
		close(sockFd);
		return -1;
	}
	printf("send ok!\n");
	//关闭套接字
	sleep(10);
	close(sockFd);
	return 0;
}

如果服务器突然停止,在重新启用,会出现下面的情况
在这里插入图片描述
在创建完socket套接字设置如下属性可以解决该情况

	int nOptval;
    if (setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR,(const void *)&nOptval , sizeof(int)) < 0)//可以运行多个实例,一起接收广播信息
    {
        perror("setsocket error\n");
        return -1;
    }

http://www.kler.cn/a/155214.html

相关文章:

  • 微服务各组件整合
  • JVM 中的完整 GC 流程
  • SQL,力扣题目1127, 用户购买平台
  • Linux 常用操作指令大揭秘(下)
  • 如何在算家云搭建Peach-9B-8k-Roleplay(文本生成)
  • 微擎框架php7.4使用phpexcel导出数据报错修复
  • 《凤凰项目》读书笔记
  • LeetCode刷题笔记第80题:删除有序数组中的重复项 II
  • pandas基础1
  • 观察者设计模式
  • ZooKeeper 如何保证数据一致性?
  • 二叉树链式结构的实现和二叉树的遍历以及判断完全二叉树
  • CentOS配置本地源
  • Python 内置异常
  • 内存函数​(memcpy、memmove、memset、memcmp)
  • 奇葩问题:arp缓存、ip地址冲突(实际是ip地址被占用导致arp缓存出现问题)
  • GEE:不同方向的线性检测算子
  • 【C语言学习疑难杂症】第9期:关于%*s以及%*d等的使用
  • 点云从入门到精通技术详解100篇-基于三维点云的工件曲面轮廓检测与机器人打磨轨迹规划(下)
  • Raft 算法
  • C# Onnx 阿里达摩院开源DAMO-YOLO目标检测
  • 采集工具-免费采集器下载
  • ARM架构基础简介
  • SCAU:各位数字
  • python 图书馆选座小程序源码
  • css如何设置文本添加下划线