利用SOCKET套接字进行TCP服务器端和客户端简单搭建

TCP(Transport Control Protocol)指传输控制协议

Socket:1.是一种编程接口 2.是一种特殊的文件描述符(everything in unix is a file )

               3.并不仅限于TCP/IP协议;4.面向链接(transmission control protocol -TCP/IP)

Socket作为一个通用的网络编程接口被需要是因为:TCP/IP协议被集成到操作系统的内核中,引入新型的io操作。它可以被理解成独立于具体协议的网络编程接口;

 

 Server:(Tcp服务器的创建流程)

  1. 创建并打开套接字 socket()
  2. 绑定ip地址(本机地址)和端口  bind()
  3. 创建监听队列 listen()
  4. 等待并建立连接 accept()
  5. 收发消息数据传输 read/write  recv/send ()
  6. 关闭套接字 close()
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#define M 30
void *pthrFunc1(void *arg)
{
	char buf[M];
	int connFd = *((int *)arg);
	while(1)
	{
		memset(buf,0,sizeof(buf));
		//printf("send:");
		scanf("%s",buf);
		if(0 == strcmp(buf,"quit"))
		{
			break;
		}   
		int ret = send(connFd,buf,sizeof(buf),0);
		if(ret < 0)
		{
			perror("send error");
			close(connFd);
			return NULL;
		}
	}
	return NULL;
}

void *pthrFunc2(void *arg)
{
	char buf[M];
	int ret;
	int connFd = *((int *)arg);
	while(1)
	{
		int ret = recv(connFd,buf,sizeof(buf),0);
		if(ret < 0)
		{
			perror("recv error");
			close(connFd);
			return NULL;
		}
		if(0 == ret)
		{
			break;
		}
		printf("recv:%s\n",buf);
		
	}
	return NULL;
}


int main()
{
	//创建并打开套接字
	int sockFd = socket(PF_INET,SOCK_STREAM,0);
	if(sockFd < 0)
	{
		perror("socket error");
		return -1;
	}
	//绑定服务器地址信息
	struct sockaddr_in servAddr = {0};
	servAddr.sin_family = PF_INET;
	servAddr.sin_port = htons(8888);
	servAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
	int ret = bind(sockFd,(struct sockaddr *)&servAddr,sizeof(servAddr));
	if(ret < 0)
	{
		perror("bind error");
		return -1;
	}
	printf("bind OK\n");
	//创建监听队列
	ret = listen(sockFd,10);
	if(ret < 0)
	{
		perror("listen error");
		close(sockFd);
		return -1;
	}
	printf("listen OK");
	//等待并建立连接
	struct sockaddr_in cliAddr = {0};
	socklen_t len = sizeof(cliAddr);
	int connFd = accept(sockFd,(struct sockaddr *)&cliAddr,&len);
	if(connFd < 0)
	{
		perror("accept error");
		close(sockFd);
		return -1;
	}
	printf("IP:%s,PORT:%d,accept OK\n",inet_ntoa(cliAddr.sin_addr),ntohs(cliAddr.sin_port));
	//创建两个子线程,一个循环写一个循环读
	pthread_t pth1,pth2;
	pthread_create(&pth1,NULL,pthrFunc1,&connFd);
	pthread_create(&pth1,NULL,pthrFunc2,&connFd);

	//主线程等待回收子线程
	pthread_join(pth1,NULL);
	pthread_join(pth2,NULL);

	//关闭套接字
	close(sockFd);
	close(connFd);

	return 0;
}

 Client:(Tcp客户端的创建流程)

  1. 创建套接字 socket()
  2. 绑定ip地址和端口号 bind()//该步骤客户端可以省略
  3. 与服务器端建立连接 connect()
  4. 收发消息,传输数据 read/write recv/send
  5. 关闭套接字 close()
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>

#define M 30
void *pthrFunc1(void *arg)
{
	char buf[M];
	int sockFd = *((int *)arg);
	while(1)
	{
		memset(buf,0,sizeof(buf));
		//printf("send:");
		scanf("%s",buf);
		if(0 == strcmp(buf,"quit"))
		{
			break;
		}
		int ret = send(sockFd,buf,sizeof(buf),0);
		if(ret < 0)
		{
			perror("send error");
			close(sockFd);
			return NULL;
		}
	}
	return NULL;
}
void *pthrFunc2(void *arg)
{
	char buf[M];
	int ret;
	int sockFd = *((int *)arg);
	while(1)
	{
		int ret = recv(sockFd,buf,sizeof(buf),0);
		if(ret < 0)
		{
			perror("recv error");
			close(sockFd);
			return NULL;
		}
		if(0 == ret)
		{
			break;
		}
		printf("recv:%s\n",buf);
		
	}
 	return NULL;
}

int main()
{
	char servIP[M];
	printf("servIP:");
	scanf("%s",servIP);
	//创建并打开套接字
	int sockFd = socket(PF_INET,SOCK_STREAM,0);
	if(sockFd < 0)
	{
		perror("socket error");
		return -1;
	}
	printf("socket OK\n");
	//连接服务器
	struct sockaddr_in servAddr = {0};
	servAddr.sin_family = PF_INET;
	servAddr.sin_port = htons(8888);
	servAddr.sin_addr.s_addr = inet_addr(servIP);//服务器ip
	int ret = connect(sockFd,(struct sockaddr *)&servAddr,sizeof(servAddr));
	if(ret < 0)
	{
		perror("connect error");
		close(sockFd);
		return -1;
	}
	printf("connect OK\n");
	//创建两个子线程,一个循环写一个循环读
	pthread_t pth1,pth2;
	pthread_create(&pth1,NULL,pthrFunc1,&sockFd);
	pthread_create(&pth2,NULL,pthrFunc2,&sockFd);
	//主线程等待回收子线程
	pthread_join(pth1,NULL);
	pthread_join(pth2,NULL);

	//关闭套接字
	close(sockFd);
	return 0;
}

感谢观看!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

......……_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值