学习了课程后参考的rtsp的数据传输框架后写下的tcp server

顺序
main
server_init()–函数
server_listen() --线程
dealwithmsg()–线程

服务器

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>

#define SERPORT		7777 		//定义端口号 大于5000的端口是预留的
#define SERADDR		"192.168.1.141"
#define BACKLOG		100        //定义等待的列表个数
#define endcode		"exit"

pthread_t thlisten;
int ret = -1;
char recvbuf[100];
int fdAccept = -1;
int socketfd = -1;
//int cnt = 0;

void* dealwithmsg(void* pParma)
{
	pthread_detach(pthread_self());
	
	char str[] = "end"; // substring needle
	char *strptr = str;
	while(1)
	{	
		//ret = recv(fdAccept,recvbuf,sizeof(recvbuf),0);
		ret = read(fdAccept,recvbuf,sizeof(recvbuf));
		//perror
		if (-1 == ret)
		{
			//perror("recv");
			perror("read");
			printf("return = %d\n",ret);
			return (void*)(-1);
		}
		if(ret == 0)
		{
			printf("客户端意外断开\n");
			break;
		}
		else if(NULL == (strstr(recvbuf,str)))
		{
			printf("成功接收了%d个字节\n",ret);
			printf("接收到的是%s\n",recvbuf);
			memset(recvbuf,0,sizeof(recvbuf));
		}	
		else
		{
			printf("客户端断开了与服务器的链接\n input \"exit\" to close server or wait until the next client connect.\n");
			close(fdAccept);
			 
			break;
		}
	}
	
	return NULL;
	
}



void *server_listen(void* pParma)
{
	printf("---server listen thread\n");
	int socketfd = -1;
	int reuse = 0;
	
	struct sockaddr_in seraddr = {0};	//因为IPv4,所以用sockaddr_in
	seraddr.sin_family = AF_INET; 		//设置地址族为ipv4
	seraddr.sin_port = htons(SERPORT);	//设置端口号,注意htons网络字节序 
	seraddr.sin_addr.s_addr = inet_addr(SERADDR);	//设置IP地址
	
	struct sockaddr_in addrAccept = {0};	
	socklen_t len = sizeof(struct sockaddr_in);
	
	pthread_t thMsg;
	
	//socket
	socketfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1 == socketfd)
	{
		perror("socket");
		return (void*)(-1);
	}
	printf("socket...\n\ropen socked fd successed... socketfd = %d\n",socketfd);
	
	//set address reuse
	ret = setsockopt(socketfd,SOL_SOCKET,SO_REUSEADDR,(void *)&reuse,sizeof(int));
	if(ret < 0)
	{
		perror("setsockopet error\n");
		return (void*)(-1);
    } 
	
	//bind
	ret = bind(socketfd,(const struct sockaddr*)&seraddr,sizeof(seraddr));
	if (ret < 0)
	{
		perror("bind");
		return (void*)(-1);
	}
	printf("bind...\r\nbind successed...\n");
	
	//listen
	ret = listen(socketfd,BACKLOG);
	if (-1 == ret)
	{
		perror("listen");
		return (void*)(-1);
	}
	printf("listen...\r\nlisten successed...\n");
	
	//accept
	while((fdAccept = accept(socketfd, (struct sockaddr *)&addrAccept, &len)) >= 0)
	{
		printf("accept...\r\naccept success... fdAccept = %d\n",fdAccept);
		
		pthread_create(&thMsg, NULL, dealwithmsg, NULL);
		// cnt++;
		// if(cnt > 3)
		// {
			// break;
		// }
	}
	if(-1 == fdAccept)
	{
		perror("accept");
		return (void*)(-1);
	}
	printf("----- server_listen Exit !! \n");
	
	
	return NULL;
}



int server_init(void)
{
	printf("---server init sub function\n");
	pthread_create(&thlisten, NULL, server_listen, NULL);
	return 0;
}


int main(int argc,char* argv[])
{
	char buf[10] ={0};
	printf("---server main function\n");
	server_init();
	while(1)
	{
		printf("----- please intput \"exit\" to exit server...\n");
		scanf("%s",buf);
		
		if(0 != (strcmp(buf,endcode)))
		{
			usleep(1000);
		}
		else
		{
			break;
		}
	}//如果不加上while(1)框住的话,scanf阻塞一次后if判断后就直接return 0 结束了,根本不在乎输入什么,所以需要while(1)一直判断
	
	return 0;
}

客户端

客户端代码跟之前的差不多,没改动多少

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

#define SERPORT		7777				//服务器开放的端口号
#define SERADDR		"192.168.1.141"   	//服务器开放的IP地址

char sendbuf[100] = "hello";

int main(void)
{
	struct sockaddr_in cliaddr = {0};
	int ret = -1;
	//第一步,先socket打开文件描述符
	int sockfd = -1;
	sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1 == sockfd)
	{
		perror("socket");
		return -1;
	}
	printf("socket\n打开文件描述符成功\n");
	
	//第二步 通过connect连接服务器
	cliaddr.sin_family = AF_INET; //设置地址族为ipv4
	cliaddr.sin_port = htons(SERPORT);//设置端口号 大于5000的端口是其他服务器预留的,还要设置字节序
	cliaddr.sin_addr.s_addr = inet_addr(SERADDR);	// 设置IP地址
	ret = connect(sockfd,(const struct sockaddr*)&cliaddr,sizeof(cliaddr));
	if (ret < 0)
	{
		perror("connect");
		return -1;
	}
	printf("与服务器connect成功\n");

	char str[] = "end"; // substring needle
	char *strptr = str;
	while(1)
	{
		printf("请输入要发送的内容\n");
		scanf("%s",sendbuf);
		if(NULL == (strstr(sendbuf,strptr)))
		{
			ret  = send(sockfd,sendbuf,strlen(sendbuf),MSG_NOSIGNAL);
			if (-1 == ret)
			{
				perror("send");
				return -1;
			}
			printf("发送了%d个字符\n",ret);
			printf("发送的信息是%s \n",sendbuf); 
		}
		else if(0 == strlen(sendbuf))
		{
			printf("you did not send anything!\n"); //其实没用上这里
		}
		else
		{
			ret  = send(sockfd,sendbuf,strlen(sendbuf),0);
			printf("close client\n");
			break;
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值