利用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 
#include 
#include 
#include 
#include 
#include 
#include 
#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 
#include 
#include 
#include 
#include 
#include 
#include 

#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;
}

感谢观看!

你可能感兴趣的:(tcp/ip,网络,unix)