socket學習記錄

被逼瘋的小肖發表於2020-12-01

socket學習記錄

/*tcp_server.c
*伺服器程式設計流程:
* 1.建立socket                                     ---->   socket()
* 2. 繫結IP和埠號                                ---->   bind()
* 3. 設定最大連線數                                ---->   listen()
* 4. 阻塞監聽客戶端連線                            ---->   accept()
    (會返回新的檔案描述符,用於與客戶端通訊)    
* 5. 使用完畢後,關閉socket						   ---->   close()
*     (此程式用於演示流程,把close寫在while外面,實際上沒有關閉) 
*	
* 至此,前面執行成功的話,伺服器就建立好了,後面就可以讀寫資訊了
*以下示例程式實現:
*①將客戶端的IP地址和埠號列印出來;
*②伺服器將接收到的資料列印到螢幕;
*③伺服器將接收到的小寫字母轉換成大寫字母返回給客戶端


*/


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

#define SERV_PORT 9527  
#define BUFFSIZE 1024

int main(void)
{
	int lfd, cfd, res;
	
	char buff[BUFFSIZE], client_ip[1024];                                          
	struct sockaddr_in serv_addr, client_addr;                 //檢視結構體 man 7 ip
	socklen_t client_addr_len;

	//開啟一個網路通訊埠,返回檔案描述符,後續與伺服器建立連線使用
	lfd = socket(AF_INET, SOCK_STREAM, 0);
	if (lfd == -1)
	{
		printf("socket error!");
	}
	
	serv_addr.sin_family = AF_INET;                       //AF_INET        IPv4協議
	serv_addr.sin_port = htons(SERV_PORT);                //htons把無符號短整形主機位元組順序轉變為網路位元組順序,實際上就是將計算機的小端格式轉為網路位元組序的大端格式
														  //此處為埠號,使用man htons檢視詳情
	serv_addr.sin_addr.s_addr =htonl(INADDR_ANY);		  //INADDR_ANY巨集表示本地的任意IP地址

	res = bind(lfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));
	if(res == -1)
	{
		printf("bind error!");
	}

	listen(lfd, 128);     //128為最大上限數
	client_addr_len = sizeof(client_addr);    
	cfd = accept(lfd, (struct sockaddr*)&client_addr, &client_addr_len);                 //阻塞監聽客戶端連線
	if(cfd == -1)
	{
		printf("accept error!");
	}
	printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");	
	printf("client ip:%s       port:%d\n",inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, sizeof(client_ip)),
			ntohs(client_addr.sin_port));
	printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>:>>>>>>\n");


	//如果建立連線成功,則開始進入資料處理(使用者自定義)
	while(1)
	{
		res = read(cfd, buff, sizeof(buff));
		write(STDOUT_FILENO, buff, res);   //寫到螢幕上
	
		for (int i =0; i< res; i++)
		{
			buff[i] = toupper(buff[i]);        //轉換成大寫再寫回buff
		}
	
		write(cfd, buff, res);            //寫res個到buf中
	}
	close(lfd);
	close(cfd);
}

/*tcp_client.c
*客戶端程式設計流程:
* 1.建立socket                                     ---->   socket()
* 2. 與伺服器建立連線                              ---->   connect()
* 3. 使用完畢後,關閉socket						   ---->   close()
*     (此程式用於演示流程,把close寫在while外面,實際上沒有關閉) 
*  
* 至此,前面執行成功的話,客戶端與伺服器就建立好了,後面就可以讀寫資訊了
*以下示例程式實現:
*	傳送小寫hello到伺服器,伺服器接收到後轉為大寫,發回給客戶端,客戶端接收並列印到螢幕上
*/


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

#define SERV_PORT 9527  
#define BUFFSIZE 1024
#define SEVER_IP "172.21.94.59"          //填寫你自己伺服器繫結的IP地址,ifconfig檢視
#define SERVER_PORT 9527                 //伺服器繫結的埠號

int main(void)
{
	int sockfd;
	int i, n;
	char *str="hello\n";
	char rec_buf[BUFFSIZE];
	
	struct sockaddr_in servaddr;
	
	/* char buff[BUFFSIZE], client_ip[1024];    */                                       
/* 	struct sockaddr_in serv_addr, client_addr;                 //檢視結構體 man 7 ip
	socklen_t client_addr_len; */

	//開啟一個網路通訊埠,返回檔案描述符,後續與伺服器建立連線使用
	sockfd = socket(AF_INET, SOCK_STREAM, 0);                     //IPV4    TCP
	if (sockfd == -1)
	{
		printf("socket error!");
	}
	
	servaddr.sin_family = AF_INET;
	inet_pton(AF_INET, SEVER_IP, &servaddr.sin_addr);      //將IP轉換後放入servaddr.sin_addr中
	servaddr.sin_port = htons(SERVER_PORT);               //轉換埠
	
	connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
	
	while(1)
	{
		
		//printf("client is wiitting!\n");
		write(sockfd, str, strlen(str));
		n = read(sockfd, rec_buf, BUFFSIZE);
		write(STDOUT_FILENO, rec_buf, n);
	
	}	
	
	close(sockfd);
		
	
}