TCP協議服務端和客戶端的連線與通訊

北极甜虾哟發表於2024-06-09

服務端

#include <stdio.h>
#include <errno.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//TCP伺服器程式碼   ./xxx   port


int main(int argc, char const *argv[])
{
	//1.建立TCP套接字
	int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (tcp_socket == -1)
	{
		fprintf(stderr, "tcp socket error,errno:%d,%s\n",errno,strerror(errno));
		exit(1);
	}

	//2.繫結自身的IP地址和埠
	struct sockaddr_in  host_addr;

	host_addr.sin_family 		= AF_INET; 						//協議族,是固定的
	host_addr.sin_port   		= htons(atoi(argv[1]));			//目標埠,必須轉換為網路位元組序
	host_addr.sin_addr.s_addr   = htonl(INADDR_ANY);		    //目標地址  INADDR_ANY 這個宏是一個整數,所以需要使用htonl轉換為網路位元組序

	bind(tcp_socket,(struct sockaddr *)&host_addr, sizeof(host_addr));

	//3.設定監聽  佇列最大容量是5
	listen(tcp_socket,5);

	//4.等待接受客戶端的連線請求
	struct sockaddr_in  client;
	socklen_t client_len = sizeof(client);

	
	int connect_fd = accept(tcp_socket,(struct sockaddr *)&client,&client_len); //會阻塞
	char buf[128] = {0};

	//5.說明雙方建立連線,此時可以接收資料
	while(1)
	{
		
		read(connect_fd,buf,sizeof(buf));
		printf("recv from [%s],data is = %s\n", inet_ntoa(client.sin_addr) ,buf);
		bzero(buf,sizeof(buf));
	}


	return 0;
}

客戶端

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

#define PORT 60001     //可修改

// 執行TCP客戶端可執行檔案   ./xxx  伺服器埠  伺服器地址

int main(int argc,char *argv[])
{
	//檢查引數有效性
	if (argc != 3)
	{
		fprintf(stderr, "argument is invaild ,errno:%d,%s\n",errno,strerror(errno));
		exit(1);
	}

	//1.建立UDP套接字             
	int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (tcp_socket == -1)
	{
		fprintf(stderr, "udp socket error,errno:%d,%s\n",errno,strerror(errno));
		exit(1);
	}

  //2.繫結自身的IP地址和埠
	struct sockaddr_in  host_addr;

	host_addr.sin_family 		= AF_INET; 				//協議族,是固定的
	host_addr.sin_port   		= htons(PORT);			//目標埠,必須轉換為網路位元組序
	host_addr.sin_addr.s_addr   = htonl(INADDR_ANY);	//目標地址 "192.168.64.xxx"  已經轉換為網路位元組序  INADDR_ANY

	bind(tcp_socket,(struct sockaddr *)&host_addr, sizeof(host_addr));



	//3.向目標服務端傳送訊息,需要設定目標埠和目標地址
    struct sockaddr_in  dest_addr;
    socklen_t dest_len = sizeof(dest_addr);
	dest_addr.sin_family 		= AF_INET; 						//協議族,是固定的
	dest_addr.sin_port   		= htons(atoi(argv[1]));			//伺服器埠,必須轉換為網路位元組序
	dest_addr.sin_addr.s_addr   = inet_addr(argv[2]);			//伺服器地址 "192.168.64.xxx"  

    //申請緩衝區
	char buf[128] = {0};

    //4.向服務端連線請求
   int temp = connect(tcp_socket, (struct sockaddr *)&dest_addr,dest_len);

   //錯誤處理,如果connect返回值小於0則連線請求失敗
   if(temp < 0)
   {
        //輸出錯誤原因
        fprintf(stderr, "udp socket error,errno:%d,%s\n",errno,strerror(errno));
        return -1;//失敗則退出程式
   }

	//5.說明雙方建立連線,此時可以傳送資料
    while(1)
    {
        printf("please input:");
        scanf("%s",buf);
        
        //向服務端傳送資料
        write(tcp_socket, buf,sizeof(buf));
        bzero(buf,sizeof(buf));
    }

	return 0;

}

相關文章