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

目录

服务端

第一步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;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,你可以参考以下的C语言代码编写TCP服务接收客户信息: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main() { int listen_fd, conn_fd; struct sockaddr_in serv_addr, client_addr; socklen_t client_addr_len; char buffer[1024]; int n; // 创建一个TCP套接字 listen_fd = socket(AF_INET, SOCK_STREAM, 0); if(listen_fd < 0) { printf("socket error: %s\n", strerror(errno)); exit(1); } // 初始化服务器地址结构 memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(9000); serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 绑定套接字和地址 if(bind(listen_fd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) { printf("bind error: %s\n", strerror(errno)); exit(1); } // 监听套接字 if(listen(listen_fd, 10) < 0) { printf("listen error: %s\n", strerror(errno)); exit(1); } printf("wait for client...\n"); while(1) { // 接受客户连接请求 client_addr_len = sizeof(client_addr); conn_fd = accept(listen_fd, (struct sockaddr*) &client_addr, &client_addr_len); if(conn_fd < 0) { printf("accept error: %s\n", strerror(errno)); continue; } printf("client connected from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); while(1) { // 接收客户发送的数据 memset(buffer, 0, sizeof(buffer)); n = read(conn_fd, buffer, sizeof(buffer)); if(n < 0) { printf("read error: %s\n", strerror(errno)); break; } else if(n == 0) { printf("client closed\n"); break; } printf("received: %s", buffer); // 发送响应给客户 if(write(conn_fd, buffer, strlen(buffer)) < 0) { printf("write error: %s\n", strerror(errno)); break; } } // 关闭连接 close(conn_fd); } // 关闭监听套接字 close(listen_fd); return 0; } ``` 这段代码展示了如何使用C语言编写一个TCP服务,它可以监听客户的连接请求,接收客户发送的数据,并向客户发送响应。如果想要编写一个TCP客户来连接这个服务,可以参考以下代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main() { int sock_fd; struct sockaddr_in serv_addr; char buffer[1024]; int n; // 创建一个TCP套接字 sock_fd = socket(AF_INET, SOCK_STREAM, 0); if(sock_fd < 0) { printf("socket error: %s\n", strerror(errno)); exit(1); } // 初始化服务器地址结构 memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(9000); serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 连接服务器 if(connect(sock_fd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) { printf("connect error: %s\n", strerror(errno)); exit(1); } while(1) { // 从标准输入读入数据 memset(buffer, 0, sizeof(buffer)); fgets(buffer, sizeof(buffer), stdin); // 发送数据到服务器 if(write(sock_fd, buffer, strlen(buffer)) < 0) { printf("write error: %s\n", strerror(errno)); break; } // 从服务接收响应数据 memset(buffer, 0, sizeof(buffer)); n = read(sock_fd, buffer, sizeof(buffer)); if(n < 0) { printf("read error: %s\n", strerror(errno)); break; } else if(n == 0) { printf("server closed\n"); break; } printf("received: %s", buffer); } // 关闭套接字 close(sock_fd); return 0; } ``` 这段代码展示了如何使用C语言编写一个TCP客户,它可以连接到服务器,发送数据给服务器,并接收服务器的响应。在这个例子中,客户从标准输入读取数据并发送给服务器,服务器将收到的数据原样返回给客户

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值