使用TCP实现双方通信

文章介绍了如何使用TCP实现双向通信,每个通信方有两个线程,一个用于发送数据,一个用于接收。通过示例代码展示了ATOB和BTOA两个通信过程。同时对比了TCP与UDP在通信方式上的差异,TCP的可靠性与连接性更强,但机制更复杂。
摘要由CSDN通过智能技术生成


前言

本期主要分享的是使用TCP网络编程实现双向通信的功能,也就是通信双方都能够同时进行消息的收发,这也是我们在平时遇到的最为经典的一种通信方式;


一、功能

通信双方都能够同时进行消息的收发,每一方都有两个线程,一个进行数据发送,另一个负责数据接收;

二、具体实现过程

1.引入库

头文件如下:

#ifndef __HEAD_H__
#define __HEAD_H__

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

#endif

2.两个通信过程

2.1 A TO B

代码如下(示例):

#include "head.h"

struct sockaddr_in sendaddr;
pthread_t tid1;
pthread_t tid2;
int sockfd = 0;

void *sendfun(void *arg)
{
	char tmpbuff[1024] = {0};
	int ret = 0;
	ssize_t nsize = 0;

	while (1)
	{
		fgets(tmpbuff, sizeof(tmpbuff), stdin);
		tmpbuff[strlen(tmpbuff) - 1] = 0;
		nsize = send(sockfd, tmpbuff, sizeof(tmpbuff), 0);
		if (nsize <= 0)
		{
			perror("fail to send");
			return NULL;
		}
		if (!strcmp(tmpbuff, "q"))
		{
			break;
		}

	}

	close(sockfd);
	pthread_cancel(tid2);
	return NULL;
}

void *recvfun(void *arg)
{
	char tmpbuff[1024] = {0};
	ssize_t nsize = 0;

	while (1)
	{
		nsize = recv(sockfd, tmpbuff, sizeof(tmpbuff), 0);
		if (nsize <= 0)
		{
			perror("fail to recv");
			return NULL;
		}
		if (!strcmp(tmpbuff, "q"))
		{
			break;
		}
		printf("recv:%s\n", tmpbuff);
	}

	close(sockfd);
	pthread_cancel(tid1);

	return NULL;
}


int main(int argc, const char *argv[])
{
	int ret = 0;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("fail to sockfd");
		return -1;
	}
	
	sendaddr.sin_family = AF_INET;
	sendaddr.sin_port = htons(50000);
	sendaddr.sin_addr.s_addr = inet_addr("192.168.209.129");

	ret = connect(sockfd, (struct sockaddr *)&sendaddr, sizeof(sendaddr));
	if (-1 == ret)
	{
		perror("fail to connect");
		return -1;
	}

	pthread_create(&tid1, NULL, sendfun, NULL);
	pthread_create(&tid2, NULL, recvfun, NULL);

	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
	return 0;
}

2.2 B TO A

#include "head.h"

struct sockaddr_in sendaddr;
pthread_t tid1;
pthread_t tid2;
int confd = 0;

void *sendfun(void *arg)
{
	char tmpbuff[1024] = {0};
	int ret = 0;
	ssize_t nsize = 0;

	while (1)
	{
		fgets(tmpbuff, sizeof(tmpbuff), stdin);
		tmpbuff[strlen(tmpbuff) - 1] = 0;
		nsize = send(confd, tmpbuff, sizeof(tmpbuff), 0);
		if (nsize <= 0)
		{
			perror("fail to send");
			return NULL;
		}
		if (!strcmp(tmpbuff, "q"))
		{
			break;
		}

	}

	close(confd);
	pthread_cancel(tid2);
	return NULL;
}

void *recvfun(void *arg)
{
	int ret = 0;
	char tmpbuff[1024] = {0};
	ssize_t nsize = 0;

	while (1)
	{

		nsize = recv(confd, &tmpbuff, sizeof(tmpbuff), 0);
		if (nsize <= 0)
		{
			perror("fail to recv");
			return NULL;
		}
		if (!strcmp(tmpbuff, "q"))
		{
			break;
		}
		printf("recv:%s\n", tmpbuff);
	}

	close(confd);
	pthread_cancel(tid1);

	return NULL;
}


int main(int argc, const char *argv[])
{
	int ret = 0;
	int sockfd = 0;
	struct sockaddr_in recvaddr;


	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("fail to sockfd");
		return -1;
	}

	recvaddr.sin_family = AF_INET;
	recvaddr.sin_port = htons(50000);
	recvaddr.sin_addr.s_addr = inet_addr("192.168.209.129");

	ret = bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
	if (-1 == ret)
	{
		perror("fail to bind");
		return -1;
	}

	ret = listen(sockfd, 10);
	if (-1 == ret)
	{
		perror("fail to sockfd");
		return -1;
	}

	confd = accept(sockfd, NULL, NULL);
	if (-1 == confd)
	{
		perror("fail to accept");
		return -1;
	}

	pthread_create(&tid1, NULL, sendfun, NULL);
	pthread_create(&tid2, NULL, recvfun, NULL);

	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
	return 0;
}

3 TCP在进行双向通信时与UDP的对比

(1)UDP是面向数据包的通信方式;要想双方通信必须绑定各自的IP地址和端口号;要么只绑定一方,但是此时若想实现双方通信,就需要另一方接收发送端的struct sockaddr *的结构体(也就是发送端的IP地址以及端口号),进而进行收发;
(2)TCP的特点是面向链接的通信方式;所以最重要的就是建立链接,发送端创建套接字直接进行connect,接收端listen,accept后生成新的通信文件描述符进行通信;所以TCP通信方式既可靠又简便,但是在实现机制比较复杂;比如TCP链接时需要进行三次握手请求,断开时需要进行四次挥手操作;

总结

本期分享的主要是使用TCP的函数接口实现TCP的网络编程实现双方通信的功能,与以前分享的一个UDP实现双方通信的实例对比得出了两者的一些不同点,更深一步掌握了网络编程的技术知识;希望各位小伙伴认真阅读,一起进步,加油哟!
最后,各位小伙伴们如果喜欢我的分享可以点赞收藏哦,你们的认可是我创作的动力,一起加油!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值