Linux-C语言编写-TCP服务端接收消息流程(含代码)简介(1)

2023-05-16

目录

服务端

第一步socket

第二步struct sockaddr_in

第三步(可以与第二步合为一个步骤)bind

第四步listen

第五步accept

第六步recv

第七步close

详细代码


服务端


第一步socket

1.操作:创建流式套接字;

2.所用函数:socket(AF_INET,SOCK_STREAM,0);

3.函数参数:AF_INET代表所使用的网际协议版本;

SOCK_STREAM代表创建的是流式套接字;

0为自动匹配该项;

4.返回值:sockfd返回值小于0时,创建失败;

int sockfd;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < -1)
{
	perror("socket err");
	return -1;
}
printf("socket sucess\n");

第二步struct sockaddr_in

1.操作:填充结构体;

2.结构体:struct sockaddr_in;

要填充的成员变量:sin_family为所使用的网际协议版本;

sin_port为端口号;sin_addr.s_addr为ip;

struct sockaddr_in serveraddr,clientaddr;
serveraddr.sin_family = AF_INET; //使用的是ipv4地址
//htons函数将主机字节序转换为网络字节序,atoi函数将字符串端口号转换为数字端口号
serveraddr.sin_port = htons(atoi(argv[1])); 
serveraddr.sin_addr.s_addr = inet_addr("0.0.0.0");//32位的IP地址

第三步(可以与第二步合为一个步骤)bind

1.操作:绑定套接字;

2.所用函数:bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));

3.函数参数:sockfd->套接字描述符;

(struct sockaddr *)&serveraddr->通用结构体指针类型的结构体;

sizeof(serveraddr)->结构体大小;

4.返回值:bind返回值小于0时,绑定失败;

if(bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) < 0)
{
	perror("bind error");
	return -1;
}
printf("bind sucess\n");

第四步listen

1.操作:监听套接字,将主动套接字转化为被动套接字等待;

2.所用函数:listen(sockfd,6);

3.函数参数:sockfd->套接字描述符;

6->任意正整数;

4.返回值:listen返回值小于0时,监听失败;

if(listen(sockfd,6) < 0)
{
	perror("listen err");
	return -1;
}
printf("listen sucess\n");

第五步accept

1.操作:阻塞并等待客户端连接,接收客户端的连接请求;

2.所用函数:accept(sockfd,NULL,NULL);

                    或accept(sockfd,(struct sockaddr *)&clientaddr,&len);

3.函数参数:

sockfd->套接字描述符;

(struct sockaddr *)&clientaddr->客户端的ip和端口号结构体对象(和serveraddr一起定义);

len->clientaddr结构体的大小(由sizeof(clientaddr);计算得);

后两位参数如果不需要可以填NULL;

4.返回值:accept返回值小于0时,接收失败;成功时会返回用于通信的描述符;

socklen_t len = sizeof(clientaddr);
int acceptfd;
acceptfd = accept(sockfd,(struct sockaddr *)&clientaddr,&len);
if(acceptfd < 0)
{
	perror("accept err");
	return -1;
}
printf("accept sucess\n");
//打印接收到的客户端的ip与端口信息
printf("client:ip = %s,port = %d\n",inet_ntoa(clientaddr.sin_addr),\
	ntohs(clientaddr.sin_port));

第六步recv

1.操作:接收并打印客户端的消息;

2.所用函数:recv(acceptfd,buf,sizeof(buf),0);

3.函数参数:acceptfd->用于通信的描述符;

buf->缓存接收消息的字符数组;

sizeof(buf)->计算数组大小;

0->接收阻塞;

最后一个参数填MSG_DONTWAIT时表示接收非阻塞;

4.返回值:recv返回值小于0时,表示接收失败,等于0时表示客户端退出;

int recvbytes = recv(acceptfd,buf,sizeof(buf),0);
if(recvbytes < 0)
{
	perror("recv err");
	return -1;
}else if(recvbytes == 0)
{
	printf("client exit\n");
}else
{
	printf("buf:%s\n",buf);
}

第七步close

1.操作:关闭描述符;

2.所用函数:close -- close(sockfd);close(acceptfd);


详细代码


/********
*服务器代码
*server.c
* 测试方式如下
* telnet "ip" "端口"
* telnet 192.168.50.16 8888
*********/

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

int main(int argc, char const *argv[])
{
	if (argc != 2)
	{
		printf("input %s <port>\n", argv[0]);
		return -1;
	}
	//1.创建流式套接字 socket
	int sockfd;
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < -1)
	{
		perror("socket err");
		return -1;
	}
	printf("socket sucess\n");

	//2.绑定套接字,ip和端口,bind
	//填充结构体
	struct sockaddr_in serveraddr, clientaddr;
	serveraddr.sin_family = AF_INET;				   //使用ipv4地址
	serveraddr.sin_port = htons(atoi(argv[1]));		   //主机字节序到网络字节序
	serveraddr.sin_addr.s_addr = inet_addr("0.0.0.0"); //32位的IP地址

	socklen_t len = sizeof(clientaddr);
	//绑定套接字
	if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
	{
		perror("bind error");
		return -1;
	}
	printf("bind sucess\n");

	//3.监听,将主动套接字转化为被动套接字等待
	if (listen(sockfd, 6) < 0)
	{
		perror("listen err");
		return -1;
	}
	printf("listen sucess\n");

	//4.阻塞等待客户端连接,即接收客户端请求

	while (1)
	{
		int acceptfd;
		acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &len);
		if (acceptfd < 0)
		{
			perror("accept err");
			return -1;
		}
		printf("accept sucess\n");
		printf("client:ip = %s,port = %d\n", inet_ntoa(clientaddr.sin_addr),
			   ntohs(clientaddr.sin_port));
		//5.循环收发消息
		int recvbytes;
		char buf[128];
		while (1)
		{
			recvbytes = recv(acceptfd, buf, sizeof(buf), 0);
			if (recvbytes < 0)
			{
				perror("recv err");
				return -1;
			}
			else if (recvbytes == 0)
			{
				printf("client exit\n");
				break;
			}
			else
			{
				printf("buf:%s\n", buf);
			}		
	    }
	//关闭
    close(acceptfd);
	close(sockfd);
	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux-C语言编写-TCP服务端接收消息流程(含代码)简介(1) 的相关文章

  • 使用 Intel RealSense 采集图片并制作机器视觉数据集

    本文章主要涉及以下工作 xff1a xff08 1 xff09 讲述如何使用 Intel RealSense 相机采集RGB图像 深度图像 伪彩色化的深度图像以及 npy 格式保存的深度数据 xff08 2 xff09 采集到的图像可适用于
  • Postman 使用教程 - 手把手教你 API 接口测试

    Postman 教程目录 API 是什么 xff1f Postman 是什么 xff1f 一 如何安装 Postman二 API 模拟工具 GoRest三 用 Postman 发出第一个 GET 请求 1 GET 请求基本操作2 带参数的
  • Socket编程(C语言实现)——TCP协议(网络间通信AF_INET)的流式(SOCK_STREAM)+报式(SOCK_DGRAM)传输

    Socket编程 目前较为流行的网络编程模型是客户机 服务器通信模式 客户进程向服务器进程发出要求某种服务的请求 xff0c 服务器进程响应该请求 如图所示 xff0c 通常 xff0c 一个服务器进程会同时为多个客户端进程服务 xff0c
  • jQuery05插件

    一 自定义插件 1 extend 类方法 1 1对象继承 xff1a extend 对象1 xff0c 对象2 1 2 扩展jQuery类方法 extend 方法名 function xff08 xff09 方法体 getMax funct
  • JavaWeb01(web环境的搭建)

    一 JDK开发工具包 1 下载和安装jdk xff1a https www oracle com index html 2 配置环境变量 JAVA HOME JDK的安装目录 path JAVA HOME bin CLASSPATH xff
  • MySql安装与使用

    今天给大家分享的是关于mysql的安装以及使用 目录 一 mysql安装步骤 二 mysql使用 一 mysql安装步骤 1 首先我们需要下载一个mysql的压缩包 xff0c 进行解压 2 接下来改变my ini文件 修改mysql安装路
  • Shiro认证及加盐加密

    目录 今天的知识是与上次所分享的知识相关联的 xff0c 在Shiro入门的基础进行编写 xff0c 上次之前的数据是死数据 放在Shiro ini 而这次是活数据 xff0c 可以连接到数据库 xff0c 运用域Relam知识 同时出于维
  • 快速掌握Nginx部署前端项目(从Nginx安装配置及部署都非常详细哦!)

    前言 xff1a 之前在Linux系统中部署了后端项目 xff0c 今天继续来给大家分享如何部署前端项目 涉及到了Nginx的简单介绍以及Nginx如何安装及配置并且能够部署前端项目 Nginx是一个轻量级的反向代理web服务器 xff0c
  • I2C协议要点总结

    I2C协议要点总结 https baijiahao baidu com s id 61 1747946282739071669 amp wfr 61 spider amp for 61 pc 一文看懂I2C协议 https zhuanlan
  • Docker数据卷&&自定义Docker镜像

    目录 宿主机与容器之间的文件拷贝 引言 xff1a 利用MySQL镜像安装MySQL服务 从容器中拷贝文件到宿主机 从宿主机拷贝文件到容器 数据卷 数据卷容器 Dockerfile自定义镜像 自定义tomcat8 xff08 熟悉几乎所有的
  • Docker自定义jdk镜像与上传阿里云

    目录 自定义jdk镜像 制作jdk8 v1 0镜像 alpine制作jdk镜像 alpine简介 基于Alpine制作jdk镜像 Alpine制作jre镜像 Docker镜像上传至阿里云 由于官方没有提供jdk xff0c 所以需要自定义j
  • OAuth2(三)

    首先把项目在本地运行起来 注意redis的配置 在地址栏输入 自动跳断点 界面截图
  • 微服务项目框架及多模块开发

    目录 项目简介 项目模式 技术栈 项目架构图 模块 案例演示 主模块 zmall common子模块 zmall user子模块 项目简介 项目模式 电商模式 xff1a 市面上有5种常见的电商模式 xff0c B2B B2C C2B C2
  • Mybatis与微服务注册

    目录 一 SpringBoot整合MybatisPlus 创建自动生成代码子模块 创建商品服务子模块 二 SpringBoot整合Freeamarker 三 SpringBoot整合微服务 amp gateway amp nginx 整合微
  • 呜呼小习题集

    在C语言中exit函数和return有相同的执行效果 xff0c 都是退出当前的函数 xff08 错 xff09 解析 xff1a 1 xff09 return是语言级别的 xff0c 它表示了调用堆栈的返回 xff1b return 是当
  • Ubuntu系统d435i相机驱动与realsense-ros安装

    安装Realsense SDK xff08 如仅仅在ROS中使用相机 xff0c 该步骤可有可无 xff0c 直接进行第二步ROS包的安装即可 xff09 下载安装包 打开终端 xff0c 运行命令 xff1a git clone http
  • 485通讯接受多个传感器信号发生冲突

    一共12个传感器通过485直接接到威纶通屏幕上 xff0c 通讯时有一个温度传感器和两个压力传感器信号会发生冲突 xff0c 温度传感器接通后 xff0c 两个压力传感器在屏幕上数值就不显示 xff0c 不接通的话 xff0c 就会显示 x
  • 在 Kali Linux 中如何安装 Google Chrome

    目的 我们的目标是在 Kali Linux 上安装Google Chrome Web 浏览器 同时 xff0c 请参阅附录为可能出现的问题进行排查 要求 需要获得已安装 Kali Linux 或者 Live 系统的特权 惯例 给定命令需要以
  • c++中.和::的区别

    xff1a xff1a 为作用域运算符 xff0c A xff1a xff1a B表示作用域A中的名称B xff0c A可以是类 空间 结构 xff1b 主要用于在类外定义类内函数 xff0c 例如 xff1a void A xff1a x
  • android测试之getevent/sendevent

    android测试之getevent sendevent https blog csdn net u013478557 article details 26063409 Android系统getevent用法 https www cnblo

随机推荐