1. 程式人生 > >linux下通訊伺服器端(普通)

linux下通訊伺服器端(普通)

#include <stdio.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>

#include <arpa/inet.h>
#include <string.h>			//bzero

#include <unistd.h>

#define PORT 3333
#define MAX_SIZE 1024

int main(){

	int sockfd;		//socket建立檔案描述符
	int opt;		//設定套接字
	int new_fd;		//接受套接字的描述符

	struct sockaddr_in server_addr;		//主機
	struct sockaddr_in client_addr;		//客戶端

	int n_read;							//讀到的位元組數
	char buffer[MAX_SIZE];				//

	//建立通訊端點,返回一個檔案描述符
	//第一個引數:表示協議簇:用AF_INET 使用IPv4協議
	//第二個引數:指定Socket型別 —— 流式套接字SOCK_STREAM
	//第三個引數:當第三個引數為0時,會自動選擇第二個引數型別對應的預設協議。
	//正確返回套接字,失敗返回-1
	//注意:type和protocol不可以隨意組合,如SOCK_STREAM不可以跟IPPROTO_UDP組合。
	if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0){
		
		perror("socket error!");
		exit(1);
	}
	printf("socket success!\n");
	
	//設定套接字
	//int getsockopt(int sockfd, int level, int optname,void *optval, socklen_t *optlen);
	//sockfd:建立的套接字
	//level:被設定的選項的級別,如果想要在套接字級別上設定選項,就必須把level設定為 SOL_SOCKET
	//接上; Socket描述符選項
	//optname:SO_REUSEADDR BOOL 允許套介面和一個已在使用中的地址捆綁
	//optval:指標,指向存放選項待設定的新值的緩衝區。
	//optlen:optval緩衝區長度。
	//這裡使用int opt = 1;即socket可重用
	//正確返回0。失敗返回-1;
	if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)) < 0){

		perror("set socket option error!\n");
		exit(1);
	}
	
	//bind繫結一個固定的網路地址和埠號(主機的地址和埠)
	//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
	//sockfd:建立的套接字
	//addr:是一個通用指標型別,addr引數實際上可以接受多種協議的
	//sockaddr結構體,它們的長度各不相同,所以需要第三個引數addrlen指定結構體的長度
	
	

	//繫結前設定結構體
	bzero(&server_addr,0);
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.sin_addr.s_addr = inet_addr("192.168.1.89");	
	

	//正式繫結
	//成功返回0,失敗返回-1
	if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0){

		perror("bind error\n");
		exit(1);
	}
	printf("bind success!\n");
	
	//監聽套接字上的連線
	//成功返回0,失敗返回-1
	//int listen(int sockfd, int backlog)
	//sockfd:檔案描述符
	//backlog:引數定義的最大長度
#if 1
	if( listen(sockfd,5) < 0 ){
		
		perror("listen error\n");
		exit(1);
	}
	printf("listen success!\n");
#endif
	printf("accept loading!\n");
	
	//等待三次握手第二次,獲得new_fd,就是對第二次握手訊息的確認
	//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
	//接受套接字上的連線:struct sockaddr_in client_addr,接受客戶端的連線
	int ser_size = sizeof client_addr;
	if( (new_fd = accept(sockfd,(struct sockaddr *)&client_addr,(socklen_t *)&ser_size)) < 0){

		perror("accept error!\n");
		exit(1);
	}
	printf("accept success!\n");
	
	while(1){

		printf("read loading\n");
		
		//從檔案描述符讀取資料
		//ssize_t read(int fd, void *buf, size_t count);
		n_read = read(new_fd,buffer,sizeof(buffer));

		if(n_read <= 0){
			
			perror("read client message error");
			exit(1);
		}
		buffer[n_read] = '\0';

		printf("read msg = %s\n",buffer);
		
	}

	







	return 0;
}