Linux:UDP

TCP服务器并发处理多个客户端

多进程&多线程
单线程服务器端不能并发处理,多线程处理并发

TCP特点:面向连接的,可靠的,流式服务

  1. 三次握手,四次挥手
  2. connect语句发起连接之后开始进程握手,accept语句,send语句
    在close之后进行四次挥手
  3. 可靠性如何保证:应答确认,超时重传,滑动窗口,乱序重排,去重
  4. 流式服务,send和receive不对应 (粘包问题)

UDP特点:无连接,不可靠,数据报
UDP服务器客户端的编程流程
在这里插入图片描述

netstat状态:接受缓冲区和发送缓冲区,当前字节数,以及使用的进程端口号

TCP服务器端代码:

#include<stdio.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>

int create_socket();

void* thread_fun(void* arg)
{
    
    
	int c = (int)arg;
	while (1)
	{
    
    
		char buff[128] = {
    
     0 };
		int n = recv(c, buff, 1, 0);
		if (n <= 0)
		{
    
    
			break;
		}
		printf("recv(%d)=%s\n", c, buff);
		send(c, "ok", 2, 0);
	}
}

int main()
{
    
    
	int socketfd = create_socket();
	assert(sockfd != -1);

	while (1)
	{
    
    
		struct sockaddr_in caddr;//存放客户端地址
		int len + sizeof(caddr);
		int c = accept(sockfd, (struct sockaddr*)&caddr, &len);
		if (c < 0)
		{
    
    
			continue;
		}
		//启动线程
		pthread_t id;
		pthread_create(&id, NULL, thread_fun, (void*)c);
	}
}
int create_socket()
{
    
    
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
    
    
		return -1;
	}
	struct sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(6000);
	saddr.sin_addr.s_addr = inet_addr("127.0.0.1");

	int res = bind(sockfd, (struct sockaddr*)&saddr, sizeof(saddr));
	if (-1 == res)
	{
    
    
		return -1;
	}
	res = listen(sockfd, 5);
	if (-1 == res)
	{
    
    
		return -1;
	}
	return sockfd;
}

UDP服务器端口代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main()
{
    
    
	int sockfd = socket(AF_INET, SOCK_DGRAM, 0);//数据报服务的套接字
	assert(sockfd != -1);

	struct sockaddr_in saddr;
	memset(&saddr, 0, sizeof(saddr));
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(6000);//端口,网路字节序列,大端
	saddr.sin_addr.s_addr = inet_addr("127.0.0.1");

	int res = bind(sockfd, (struct sockaddr*)&saddr, sizeof(saddr));
	assert(res != -1);

	while (1)
	{
    
    
		struct sockaddr_in caddr;
		int len = sizeof(caddr);
		char buff[128] = {
    
     0 };

		int n = recvfrom(sockfd, buff, 127, 0, (struct sockaddr*)&caddr, &len);
		printf("rec(%d):%s\n", n, buff);

		sendto(sockfd, "ok", 2, 0, (struct sockaddr*)&caddr, sizeof(caddr));
	}
}

UDP客户端代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main()
{
    
    
	int sockfd = socket(AF_INET, SOCK_DGRAM, 0);//数据报服务的套接字
	assert(sockfd != -1);

	struct sockaddr_in saddr;//代表服务端的地址:ip,port
	memset(&saddr, 0, sizeof(saddr));
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(6000);//指定服务器端口
	saddr.sin_addr.s_addr = inet_addr("127.0.0.1");//指定服务器ip

	while (1)
	{
    
    
		char buff[128] = {
    
     0 };
		printf("input:\n");

		fgets(buff, 128, stdin);

		if (strncmp(buff, "end", 3) == 0)
		{
    
    
			break;
		}

		sendto(sockfd, buff, strlen(buff), 0, (struct sockaddr*)&saddr, sizeof(saddr));
		memset(buff, 0, 128);
		int len = sizeof(saddr);
		recvfrom(sockfd, buff, 127, 0, (struct socksaddr*)&saddr, &len);
		printf("buff=%s\n", buff);
	}
	close(sockfd);
}

猜你喜欢

转载自blog.csdn.net/qq_48580892/article/details/120488127
今日推荐