线程+网络编程基础实现简易双人聊天

目录

1.头文件

2.服务端代码

2.1 创建子线程函数

2.2 接收信息函数

2.3 发送信息函数

2.4 主函数

3.客户端代码

3.1 接收信息函数

3.2 发送信息函数

3.3 主函数

4. 运行结果


1.头文件

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

2.服务端代码

2.1 创建子线程函数

void *thread(void *p)
{
	pthread_t tid1,tid2;
	int connFd=*((int *)p);
	char buf[100];
	pthread_create(&tid1,NULL,threadsend,p);
	pthread_create(&tid2,NULL,threadrecv,p);
	return NULL;
}

2.2 接收信息函数

void *threadrecv(void *p)
{
	char buf[100];
	int connFd=*((int *)p);
	while(1)
	{
		int ret;
		memset(buf,0,sizeof(buf));
		ret=recv(connFd,buf,sizeof(buf),0);
		if(ret<0)
		{
			perror("recv error");
			return NULL;
		}
	    else if(ret==0)
		{
			exit(0);
		}
		printf("from client: %s\n",buf);
	}
}

2.3 发送信息函数

void *threadsend(void *p)
{
	int connFd=*((int *)p);
	char buf[100];
	while(1)
	{
		gets(buf);
		send(connFd,buf,sizeof(buf),0);
		printf("server send ok\n");
	}
	return NULL;
}

2.4 主函数

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;
	//创建套接字
	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));
	while(1)
	{
		pthread_t tid;
		pthread_create(&tid,NULL,thread,&connFd);
	}
	//关闭套接字
	close(listenFd);
	close(connFd);
	return 0;
}

3.客户端代码

3.1 接收信息函数

void *threadrecv(void *p)
{
	char buf[100];
	int connFd=*((int *)p);
	while(1)
	{
		int ret;
		ret=recv(connFd,buf,sizeof(buf),0);
		if(ret<0)
		{
			perror("recv error");
			return NULL;
		}
		printf("from server: %s\n",buf);
	}
}

3.2 发送信息函数

void *threadsend(void *p)
{
	int connFd=*((int *)p);
	char buf[100];
	while(1)
	{
		gets(buf);
		if(strcmp(buf,"quit")==0)
		{
			exit(0);
		}
		send(connFd,buf,sizeof(buf),0);
		printf("client send ok\n");
	}
	return NULL;
}

3.3 主函数

int main()
{
	int sockFd = -1;
	//服务器的地址结构
	struct sockaddr_in servAddr = {0};
	int ret;
	//创建套接字
	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;
	}
	pthread_t tid1,tid2;
	printf("connect ok!\n");
	while(1)
	{
		pthread_create(&tid1,NULL,threadsend,&sockFd);
		pthread_create(&tid2,NULL,threadrecv,&sockFd);
	}
	//关闭套接字
	close(sockFd);
	return 0;
}

4. 运行结果

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值