Socket编程--TCP连接以及并发处理

流程图

网络传输流程:
在这里插入图片描述
TCP连接:
在这里插入图片描述

api

客户端:

  • socket: 创建套接字
    domain: AF_INET :IPv4
    type: SOCK_STREAM(tcp)、SOCK_DGRAM(udp)
    protocol: 0 默认协议
    返回值:成功返回一个新的套接字,失败返回­1,设置errno
int socket(int domain, int type, int protocol);

  • connect: 连接服务器(客户端执行)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockdf:
参数是成功调用socket()返回的套接字。
addr:
传入参数,指定服务器端地址信息,含IP地址和端口号
addrlen:
传入参数,如IPV4传入sizeof(struct sockaddr_in)大小
如果调用成功,表示连接已经建立(三次握手完成),返回0。否则返回 ­1并将错误码代存放于全局变量errno
之中。

服务端:

  • bind: 给本地套接字赋予地址和端口号
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd:
socket套接字
addr:
填写IP地址、端口号、协议族等信息。
addrlen:
addr结构体实例的大小
返回值:
成功返回0,失败返回­1, 设置errno
  • listen : 给连接排队
int listen(int sockfd, int backlog);
sockfd:
参数为成功调用socket函数返回的套接字,并已经成功调用了bind()。
backlog:
参数告诉套接字在忙于处理上一个请求时,还可以接受多少个进入的请求,换句话说,这决定了挂起连接的队
列的大小。
  • accept: 等待客户
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockdf:
参数为成功调用socket函数返回的套接字,并已经成功调用了 bind()listen()
addr:
传出参数,返回连接客户端地址信息,含IP地址和端口号。(如果使用IPv4地址族,那么它需要我们填个指向
sockaddr_in结构的指针)
addrlen:
传入传出参数(值­结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小
返回值:
成功返回一个新的socket文件描述符,用于和客户端通信,失败返回­1,设置errn

Socket IO:

  • send:客户端/服务器发送数据
 int send( SOCKET s, const char FAR *buf, int len, int flags ); 
 // flag 通常为0
  • recv:客户端/服务器接收数据
int recv( SOCKET s, char FAR *buf, int len, int flags); 
  • read
int read(int sockfs, void *buf, size_t nbytes);
  • write
int write(int sockfd, void *buf, size_t nbytes);

阻塞IO/非阻塞IO

阻塞:等待某个条件的满足才能往下执行,非阻塞反之。

设置非阻塞模式:

int flag = fcntl(sockfd,F_GETFL,0);
flags |= O_NONBLOCK;
fcntl(sockfd,F_SETFL,flags);

阻塞IO:
accept(), 需要等待客户端连接, 之后继续执行
recv() 等待数据到来后继续执行
如果设置非阻塞模式,则不需要进行等待

code

连接一个客户端收发数据:
一个客户端连接对应一个accept,在listen()执行后,accept()未执行前,客户端进行连接,accept 可以成功连接,并返回新的socket的值 , while循环处理send/recv

连接多个客户端进行收发数据:
创建线程,循环读取数据, 在while循环中, 调用accept和线程

客户端:

#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SERVER_PORT 9999
int main(int argc, char *argv[])
{
	struct sockaddr_in serveraddr;
	int sockfd, n, ret;
	char buf[] = "helloworld";
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	bzero(&serveraddr, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;
	inet_pton(AF_INET, "127.0.0.1", &serveraddr.sin_addr);
	serveraddr.sin_port = htons(SERVER_PORT);
	ret = connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
	if(ret ==1)
	perror("connect");
	ret = send(sockfd, buf, strlen(buf),0);
	if(ret ==1)
	perror("connect");
	close(sockfd);
	return 0;
}

服务器端:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>

#define BUFFER_LENGTH	128

void *routine(void *arg) {

	int clientfd = *(int *)arg;

	while (1) {
		
		unsigned char buffer[BUFFER_LENGTH] = {0};
		int ret = recv(clientfd, buffer, BUFFER_LENGTH, 0);
		if (ret == 0) {
			close(clientfd);
			break;
			
		}
		printf("buffer : %s, ret: %d\n", buffer, ret);

		ret = send(clientfd, buffer, ret, 0); // 

	}
}
int main() {
// block
	int listenfd = socket(AF_INET, SOCK_STREAM, 0);  // 
	if (listenfd == -1) return -1;
// listenfd
	struct sockaddr_in servaddr;
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(9999);

	if (-1 == bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) {
		return -2;
	}

#if 0 // nonblock
	int flag = fcntl(listenfd, F_GETFL, 0);
	flag |= O_NONBLOCK;
	fcntl(listenfd, F_SETFL, flag);
#endif

	listen(listenfd, 10);

	while (1) {
		
		struct sockaddr_in client;
		socklen_t len = sizeof(client);
		int clientfd = accept(listenfd, (struct sockaddr*)&client, &len);
		
		pthread_t threadid;
		pthread_create(&threadid, NULL, routine, &clientfd);

	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/585620.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux-进程间通信(进程间通信介绍、匿名管道原理及代码使用、命名管道原理及代码使用)

一、进程通信介绍 1.1进程间通信的目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#xff1a;多个进程之间共享同样的资源。通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它&#xff08;它们&#xff09;发生了某…

值得买科技新思路,导购电商的终点是“AI+出海”?

在以往&#xff0c;大众普遍认为品牌的消费者大多是高度忠诚人群&#xff0c;而事实上&#xff0c;非品牌忠诚者相比重度消费者&#xff0c;对促进品牌增长更为重要。 这类非品牌忠诚者被定义为摇摆的消费者群体&#xff0c;也就是那些购买品牌产品概率在20%-80%之间的消费者。…

【Unity动画系统】Animator组件的属性

介绍Animator组件的全部属性 Controller&#xff1a;动画控制器 Avatar&#xff1a;人物骨骼 Apply Root Motion&#xff1a;有一些动画片段自带位移&#xff0c;如果希望自带的位移应用在游戏对象上&#xff0c;那么就勾选&#xff1b;如果自己编写脚本&#xff0c;那么就不…

如何用智能获客开启新商机?揭秘赢销侠软件的奇效

在当今数字化竞争日益激烈的商业环境中&#xff0c;企业为了生存和发展&#xff0c;必须寻找新的途径以获取潜在客户。智能获客作为一种新型的营销方式&#xff0c;正以其高效、精准的特点改变着传统的市场开拓模式。而在这个过程中&#xff0c;自动获客软件的作用愈发凸显&…

LLM大语言模型原理、发展历程、训练方法、应用场景和未来趋势

LLM&#xff0c;全称Large Language Model&#xff0c;即大型语言模型。LLM是一种强大的人工智能算法&#xff0c;它通过训练大量文本数据&#xff0c;学习语言的语法、语义和上下文信息&#xff0c;从而能够对自然语言文本进行建模。这种模型在自然语言处理&#xff08;NLP&am…

杰发科技AC7840——SPI通信简介(1)_跑通Demo

0. 简介 一些配置项&#xff1a; CPHA&#xff1a;相序 CPLO&#xff1a;极性 看着demo需要按键&#xff0c;于是去掉按键&#xff0c;去掉打印&#xff0c;直接输出波形看逻辑分析仪的信号。 其实现在做这些demo测试应该都有逻辑分析仪&#xff0c;直接看波形更直观一点。…

分享:抖音老阳口中的选品师项目好做吗?

近年来&#xff0c;随着抖音等短视频平台的兴起&#xff0c;越来越多的博主通过分享自己的生活、知识和见解吸引了大量粉丝。其中&#xff0c;抖音博主老阳以其独特的选品眼光和专业的产品评测&#xff0c;在广大网友中树立了良好的口碑。那么&#xff0c;老阳口中的选品师项目…

【MySQL】MVCC的实现原理

【MySQL】MVCC的实现原理 MVCC简介事务的隔离级别读未提交&#xff08;Read Uncommitted&#xff09;概念分析 读已提交&#xff08;Read Committed&#xff09;概念分析结论 可重复读&#xff08;Repeatable Read&#xff09;概念分析结论 串行化&#xff08;Serializable &am…

实战—登录功能引发的逻辑漏洞

密码找回功能可能存在的漏洞 1.验证码发送后前端返回 2.验证码无次数限制可爆破 3.验证码可控/邮箱篡改为自己的接收短信验证码/手机号码篡改为自己的接收短信验证码 4.越权漏洞—>自己验证码通过改包然后修改他们密码 5.任意用户密码重置 6.密保问题在前端源码 实战…

Linux基础——Linux开发工具(上)_vim

前言&#xff1a;在了解完Linux基本指令和Linux权限后&#xff0c;我们有了足够了能力来学习后面的内容&#xff0c;但是在真正进入Linux之前&#xff0c;我们还得要学会使用Linux中的几个开发工具。而我们主要介绍的是以下几个&#xff1a; yum, vim, gcc / g, gdb, make / ma…

49. 字母异位词分组 128. 最长连续序列

49. 字母异位词分组 128. 最长连续序列 把集合里面的所有元素都放入set容器里面 定义结果最大连续数量 ans for循环遍历每个元素 先判断集合里面有没有比这个元素小1的 如果没有 说明这个元素就是序列的第一个元素 然后接着找集合里面有没有比这个元素大1的 while一直找 …

牛客NC353 回文子串的数量【中等 字符串,枚举,回文 C++/Java/Go/PHP 高频】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/3e8b48c812864b0eabba0b8b25867738 思路 参考答案C class Solution {public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可*** param str string字符串…

详解centos8 搭建使用Tor 创建匿名服务和匿名网站(.onion)

1 Tor运行原理&#xff1a; 请求方需要使用&#xff1a;洋葱浏览器&#xff08;Tor Browser&#xff09;或者Google浏览器来对暗&#xff0c;网网站进行访问 响应放需要使用&#xff1a;Tor协议的的Hidden_service 2 好戏来了 搭建步骤&#xff1a; 1.更新yum源 rpm -Uvh h…

OceanBase V4.3 发布—— 迈向实时分析 AP 的重要里程

OceanBase在2023年初&#xff0c;发布了4.x架构的第一个重要版本&#xff0c;V4.1。该版本采用了单机分布式一体化架构&#xff0c;并在该架构的基础上&#xff0c;将代表数据库可靠性的RTO降低至 8 秒以内&#xff0c;从而确保在意外故障发生后&#xff0c;系统能够在极短时间…

javafx如何一键打包成exe

javafx如何打包成exe JavaFX-Template-Native 集成jfoenix、commons-math、commons-lang3、netty&#xff0c;方便一些和底层做通信使用&#xff0c;不需要可以自行pom中去掉依赖当前使用的jdk17&#xff0c;理论上jdk14都支持采用模块化&#xff0c;支持一键打包生成很小的ex…

Threejs制作服务器机房冷却结构

这节再绘制一个机房的结构&#xff0c;因为内容比较简单&#xff0c;就只使用一个章节来介绍&#xff0c; 先来一张效果图&#xff0c; 需要两个模型&#xff1a;一个冷却设备&#xff0c;一个服务器机箱&#xff0c;我这里是从网上找来的&#xff0c;首先我们搭建一个场景&a…

solidworks出现slderrresu.dll错误如何解决?亲测有效

通过近来给客户安装SolidWorks发现&#xff0c;SolidWorks2010、SolidWorks2012、SolidWorks2014、SolidWorks2015、SolidWorks2016、SolidWorks2017都会出现这个slderrresu.dll安装错误问题&#xff1a; 其实这个错误很好解决,主要是因為安裝中文版solidworks沒有選擇安裝中文…

.NET操作 Access (MSAccess)

注意&#xff1a;新项目推荐 Sqlite &#xff0c;Access需要注意的东西太多了&#xff0c;比如OFFICE版本&#xff0c;是X86还是X64 连接字符串 ProviderMicrosoft.ACE.OleDB.15.0;Data Source"GetCurrentProjectPath"\\test.accdb//不同的office版本 连接字符串有…

Linux 虚拟主机切换php版本及参数

我使用的Hostease的Linux虚拟主机产品,由于网站程序需要支持高版本的PHP,程序已经上传到主机&#xff0c;但是没有找到切换PHP以及查看PHP有哪些版本的位置&#xff0c;因此咨询了Hostease的技术支持&#xff0c;寻求帮助了解到可以实现在cPanel面板上找到此切换PHP版本的按钮&…

亚马逊商品详情API接口:解锁亚马逊商品信息的全面视野

亚马逊商品详情API接口&#xff1a;解锁亚马逊商品信息的全面视野 在跨境电商和电商数据分析领域&#xff0c;亚马逊作为全球领先的电商平台&#xff0c;其商品信息对商家、开发者以及市场分析师来说至关重要。为了更高效地获取亚马逊平台上的商品详情&#xff0c;亚马逊商品详…