tcp单向通信

tcp单向通信_第1张图片
tcp单向通信_第2张图片
tcp单向通信_第3张图片

client.c

#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
	//1 建立通信套接字
	int fd = socket(AF_INET,SOCK_STREAM,0);
	if(fd == -1)
	{
		printf("fail to socket");
		exit(1);
	}
	//2 连接服务器
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8888);
	addr.sin_addr.s_addr =htonl(INADDR_ANY);
	int ret = connect(fd,(struct sockaddr*)&addr,sizeof(addr));
        if(ret == -1)
	{
		printf("fail to connect");
		exit(1);
	}
	//3 通信
	//int number = 1;
	while(1)
	{
		//发送数据 
		char buff[1024];
		//sprintf(buff,"你好,服务器,第%d次和你通信",number++);
                //gets(buff);
                printf("pls say sth to server:\n");
                fgets(buff,sizeof(buff),stdin);
		send(fd,buff,strlen(buff)+1,0);
		
		//接收数据 
		memset(buff,0,1024);
		int len = recv(fd,buff,sizeof(buff),0);
		if(len > 0)
		{
			printf("服务器 :%s\n",buff);
		}else if(len == 0)
		{
			printf("和服务器的连接断开\n");
			break;
		}else
		{
			perror("fail to read");
			break;
		}
		sleep(1);
	}
	//4 关闭通信套接字 
	close(fd);
 } 

server.c

#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
	//1 创建监听套接字 
	int fd = socket(AF_INET,SOCK_STREAM,0);
	if(fd == -1)
	{
		perror("fail to socket");
		exit(1);
	}
	//2 绑定我们本地的IP地址和端口号
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8888);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
	if(ret == -1)
	{
		perror("fail to bind");
		exit(1);
	}
	//3 设置监听
       ret = listen(fd,128);
       if(ret == -1)
	{
		perror("fail to listen");
		exit(1);
	}
	//4 阻塞等待,连接的到达,连接成功后返回通信用的套接字
	struct sockaddr_in caddr;
	int caddrlen = sizeof(caddr);
	int fdc = accept(fd,(struct sockaddr *)&caddr,&caddrlen);
        if(fdc == -1)
	{
		perror("fail to accept");
		exit(1);
	}
	//5 开始通信 
	while(1)
	{
		char buff[1024];
		memset(buff,0,sizeof(buff));
		int len = read(fdc,buff,1024);
		char ip[30] = {0};
		if(len > 0)
		{
			printf("客户端 %s:%d : %s \n",
			inet_ntop(AF_INET,&caddr.sin_addr,ip,sizeof(ip)),
			ntohs(caddr.sin_port),
			buff);
			write(fdc,buff,len);
		}
		if(len = 0)
		{
			printf("连接已断开\n");
			break;
		}
		if(len < 0)
		{
			perror("fail to read");
			break;
		}
	}
	//6 关闭套接字
	close(fd);
	close(fdc);
}

运行结果:
tcp单向通信_第4张图片
如果server.c改一下
tcp单向通信_第5张图片
那么运行结果变成
tcp单向通信_第6张图片
多进程实现TCP服务器开发
client.c跟上面的一样
server_fort.c

#include
#include
#include
#include
#include
#include
void handler(int sig)
{
	wait(NULL);
}
int main(int argc, char *argv[])
{
	//1 创建监听套接字 
	int fd = socket(AF_INET,SOCK_STREAM,0);
	if(fd == -1)
	{
		perror("fail to socket");
		exit(1);
	}
        //设置套接字,可以重复使用本机地址,和端口复用
         int on = 1;
         if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0) 
         {
	      perror("fail to setsockopt");
	      exit(1);
         }
	//2 绑定我们本地的IP地址和端口号
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8888);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
	if(ret == -1)
	{
		perror("fail to bind");
		exit(1);
	}
	//3 设置监听
       ret = listen(fd,128);
       if(ret == -1)
	{
		perror("fail to listen");
		exit(1);
	}
	signal(SIGCHLD,handler);
     while(1)
     {
    //4 阻塞等待,连接的到达,连接成功后返回通信用的套接字
        struct sockaddr_in caddr;
	int caddrlen = sizeof(caddr);
	int fdc = accept(fd,(struct sockaddr *)&caddr,&caddrlen);
        if(fdc == -1)
	{
		perror("fail to accept");
		exit(1);
	}
	pid_t pid = fork();
	if(pid < 0)
	{
		perror("fail to pid");
		exit(1);
	}
	if(pid == 0)
	{
	   //5 开始通信 
	 while(1)
	 {
		char buff[1024];
		memset(buff,0,sizeof(buff));
		int len = read(fdc,buff,1024);
		char ip[30] = {0};
		if(len > 0)
		{
			printf("客户端 %s:%d : %s \n",
			inet_ntop(AF_INET,&caddr.sin_addr,ip,sizeof(ip)),
			ntohs(caddr.sin_port),
			buff);
			write(fdc,buff,len);
		}
		if(len = 0)
		{
			printf("连接已断开\n");
			break;
		}
		if(len < 0)
		{
			perror("fail to read");
			break;
		}
	  }
	  	close(fdc);
	}

      }
	//6 关闭套接字
	close(fd);
}

运行结果:
tcp单向通信_第7张图片
多线程实现TCP服务器并发
client.c跟上面的一样
server_thread.c

#include
#include
#include
#include
#include
#include

struct Sss{
        struct sockaddr_in caddr;
	int fdc;
};
void *thread_fun(void *arg)
{
	struct Sss sss =*(struct Sss *)arg;
	int fdc = sss.fdc;  
	struct sockaddr_in caddr = sss.caddr;
	//5 开始通信 
	while(1)
	{
		char buff[1024];
		memset(buff,0,sizeof(buff));
		int len = read(fdc,buff,1024);
		char ip[30] = {0};
		if(len > 0)
		{
			printf("客户端 %s:%d : %s \n",
			inet_ntop(AF_INET,&caddr.sin_addr,ip,sizeof(ip)),
			ntohs(caddr.sin_port),
			buff);
			write(fdc,buff,len);
		}
		if(len = 0)
		{
			printf("连接已断开\n");
			break;
		}
		if(len < 0)
		{
			perror("fail to read");
			break;
		}
	 }
	 close(fdc);
	 pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
	//1 创建监听套接字 
	int fd = socket(AF_INET,SOCK_STREAM,0);
	if(fd == -1)
	{
		perror("fail to socket");
		exit(1);
	}
         //设置套接字,可以重复使用本机地址,和端口复用
         int on = 1;
         if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0) 
         {
	      perror("fail to setsockopt");
	      exit(1);
         }
	//2 绑定我们本地的IP地址和端口号
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8888);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
	if(ret == -1)
	{
		perror("fail to bind");
		exit(1);
	}
	//3 设置监听
       ret = listen(fd,128);
       if(ret == -1)
	{
		perror("fail to listen");
		exit(1);
	}
while(1)
 {
		//4 阻塞等待,连接的到达,连接成功后返回通信用的套接字
	 
	struct sockaddr_in caddr;
	int caddrlen = sizeof(caddr);
	int fdc = accept(fd,(struct sockaddr *)&caddr,&caddrlen);
        if(fdc == -1)
	{
		 perror("fail to accept");
		exit(1);
	}
	
	struct Sss sss;
	sss.caddr = caddr;
	sss.fdc = fdc;
	pthread_t thread;
//	pthread create(&thread,NULL,thread_fun,&fdc);
        pthread_create(&thread,NULL,thread_fun,&sss);
	pthread_detach(thread);

 }
	
	//6 关闭套接字
	close(fd);
	//close(fdc);
} 

编译命令

gcc server_thread.c -o server_thread -lpthread
然后
./server_thread

运行结果:
tcp单向通信_第8张图片
以上代码跟着b站博主敲的
地址https://www.bilibili.com/video/BV1W64y1k75t
线程池实现TCP服务器并发没弄
推荐并发网络通信-套接字通信(C/C++ 多线程)
地址https://www.bilibili.com/video/BV1F64y1U7A2

你可能感兴趣的:(网络编程,tcp/ip,服务器,网络)