TCP編程模型

文章目錄

1 TCP編程模型

先來看一下socket整體框架圖:
在這裏插入圖片描述
如下爲TCP通信模型:
在這裏插入圖片描述

TCP客戶端和服務器示例代碼:
demo_tcp_server.c:


#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>

#include <netinet/in.h>
//#include <Windows.h>
#include <pthread.h>
#include <malloc.h>
#include <string.h>

#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <netdb.h>


#include <sys/time.h>

#include <signal.h>




#define SERVER_PORT_TCP			6666
#define TCP_BACKLOG 10


/* 在sock_fd 進行監聽,在 new_fd 接收新的鏈接 */
int sock_fd, new_fd;


void printf_hex(char *buf, int len)
{
	int i;
	for(i = 0; i < len; i++)
	{
		printf("0x%x ", buf[i]);
	}

	
}


void sig_chld(int signo)
{
	pid_t pid;
	int stat;

	while((pid = waitpid(-1, &stat, WNOHANG)) > 0)
		printf("child %d terminated\r\n", pid);
	return;
}





int main(void)
{
	char command[1024];
	char *str;

	/* 自己的地址信息 */
	struct sockaddr_in my_addr;
	/*	連接者的地址信息*/
	struct sockaddr_in their_addr;
	int sin_size;

	struct sockaddr_in *cli_addr;

	/* 1 、創建socket  */
	if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		perror("socket is error\r\n");
		exit(1);
	}

	/* 主機字節順序 */
	/* 協議 */
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(6666);
	/* 當前IP 地址寫入 */
	my_addr.sin_addr.s_addr = INADDR_ANY;

	/* 將結構體其餘的都清零 */
	bzero(&(my_addr.sin_zero), 8);

	/* bind 綁定*/
	if(bind(sock_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
	{
		perror("bind is error\r\n");
		exit(1);
	}

	/* 開始監聽 */
	if(listen(sock_fd, TCP_BACKLOG) == -1)
	{
		perror("listen is error\r\n");
		exit(1);
	}

	printf("start accept\n");

	/* 因爲我們後面會創建出許多子進程來服務新的鏈接
		一旦子進程異常終止了,需要父進程來進行資源回收
	*/
	signal(SIGCHLD, sig_chld);			//在這裏處理僵死進程

	/* accept() 循環 */
	while(1)
	{
		sin_size = sizeof(struct sockaddr_in);

		if((new_fd = accept(sock_fd, (struct sockaddr *)&their_addr, (socklen_t *)&sin_size)) == -1)
		{
			perror("accept");
			continue;
		}

		cli_addr = malloc(sizeof(struct sockaddr));

		printf("accept addr\r\n");

		if(cli_addr != NULL)
		{
			memcpy(cli_addr, &their_addr, sizeof(struct sockaddr));
		}

		//處理目標
		ssize_t ret;
		char recvbuf[512];
		char *buf = "hello! I'm server!";

		while(1)
		{
			if((ret = recv(new_fd, recvbuf, sizeof(recvbuf), 0)) == -1){
				printf("recv error \r\n");
				return -1;
			}
			printf("recv :\r\n");
			printf("%s", recvbuf);
			printf("\r\n");
			sleep(2);
			if((ret = send(new_fd, buf, strlen(buf) + 1, 0)) == -1)
			{
				perror("send : ");
			}

			sleep(2);
		}

		

		close(new_fd);
	}

	
	return 0;
}



demo_tcp_client.c:


#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
//#include <Windows.h>
#include <pthread.h>
#include <malloc.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <netdb.h>


#include <sys/time.h>

#include <signal.h>




int sockfd;

//#define SERVER_IP	"106.13.62.194"
#define SERVER_IP	"127.0.0.1"

#define SERVER_PORT	6666

void printf_hex(char *buf, int len)
{
	int i;
	for(i = 0; i < len; i++)
	{
		printf("0x%x ", buf[i]);
	}

	
}


int main(void)
{
	char command[1024];
	char *str;
	/*	連接者的主機信息 */
	struct sockaddr_in their_addr;	

	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		/*	如果socket()調用出現錯誤則顯示錯誤信息並退出 */
		perror("socket");
//		exit(1);
	}

	/*	主機字節順序 */
	their_addr.sin_family = AF_INET;
	/*	網絡字節順序,短整型 */
	their_addr.sin_port = htons(SERVER_PORT);
	their_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
	/*	將結構剩下的部分清零*/
	bzero(&(their_addr.sin_zero), 8);
	if(connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
	{
		/*	如果connect()建立連接錯誤,則顯示出錯誤信息,退出 */
		perror("connect");
		exit(1);
	}

	

	ssize_t ret;
	char recvbuf[512];
	char *buf = "hello! I'm client!";
	
	while(1)
	{
		
		if((ret = send(sockfd, buf, strlen(buf) + 1, 0)) == -1)
		{
			perror("send : ");
		}

		sleep(2);
		if((ret = recv(sockfd, &recvbuf, sizeof(recvbuf), 0)) == -1){
			return -1;
		}

		printf("recv :\r\n");
		printf("%s", recvbuf);
		printf("\r\n");

		sleep(2);
	}
	

	close(sockfd);

	
	return 0;
}




參考資料:

  1. 5G物聯網雲平臺智能家居項目30天搞定
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章