linux簡單的TCP與UDP的socket程序以及機器大小端的判斷程序

分類: linux編程 C/C++隨筆 149人閱讀 評論(0) 收藏 舉報

本文只是總結一下linux下tcp與udp程序的編寫,其實不管平臺如何,簡單的tcp與udp程序的結構還是不會變的。如下所示:



tcp(基於鏈接)的簡單程序結構

udp(無連接)的程序結構

過程不在贅述,看看一個基於上面過程的簡單udp代碼:

udpserver.c

  1. #include<stdlib.h>   
  2. #include<stdio.h>   
  3. #include<string.h>   
  4. #include<sys/types.h>   
  5. #include<sys/socket.h>   
  6. #include<netinet/in.h>   
  7. #include<netdb.h>   
  8.   
  9.   
  10. #define PORT 8900   
  11.   
  12.   
  13. int main()  
  14. {  
  15.   
  16.     int sockfd;  
  17.     struct sockaddr_in server;  
  18.     struct sockaddr_in client;  
  19.     char send_buf[2048];  
  20.     char recv_buf[2048];  
  21.     int length;  
  22.     int sendnum;  
  23.     int recvnum;  
  24.     int port;  
  25.   
  26.   
  27.     port = PORT;  
  28.     int opt = SO_REUSEADDR;  
  29.       
  30.   
  31.   
  32. /*The first stage:initnial phase*/  
  33.   
  34. /*1.1 generating socket  phrahse*/  
  35.   
  36.     if (-1==(sockfd=socket(AF_INET,SOCK_DGRAM,0)))  
  37.     {  
  38.         perror("error in generate socket\n");  
  39.         exit(1);  
  40.   
  41.     }  
  42.   
  43.     #ifdef DEBUG   
  44.         printf("the sokcet id is %d\n",sockfd);  
  45.         printf("enter binding phrase....\n");  
  46.     #endif   
  47.     setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));  
  48.   
  49. /*1.2 binding the socket*/  
  50.   
  51.     memset(&server,0,sizeof(struct sockaddr));  
  52.     server.sin_family = AF_INET;  
  53.     server.sin_addr.s_addr = htonl(INADDR_ANY);  
  54.     server.sin_port = htons(port);  
  55.   
  56.     if (-1==bind(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr)))  
  57.     {  
  58.         perror("error in binding phrase\n");  
  59.         close(sockfd);  
  60.         exit(1);  
  61.   
  62.     }  
  63.   
  64.   
  65.     #ifdef DEBUG   
  66.         printf("leaving binding phrase\n");  
  67.         printf("entering data exchange phrase\n");  
  68.     #endif   
  69.   
  70.     length = sizeof(struct sockaddr_in);   
  71.   
  72. /* The Second Stage: data exchange phrase */  
  73.     while(1)  
  74.     {  
  75.         memset(&send_buf,0,sizeof(send_buf));  
  76.         memset(&recv_buf,0,sizeof(recv_buf));  
  77.           
  78.         /* receive the data from the client*/  
  79.   
  80.         recvnum=recvfrom(sockfd,recv_buf,sizeof(recv_buf),0,(struct sockaddr*)&client,&length);  
  81.       
  82.         recv_buf[recvnum]='\0';  
  83.         printf("the message from the client is %s:\n",recv_buf);  
  84.       
  85.   
  86.         sendnum = sprintf(send_buf,"hello,the guest from %s",inet_ntoa(client.sin_addr));  
  87.         sendto(sockfd,send_buf,sendnum,0,(struct sockaddr*)&client,sizeof(struct sockaddr));  
  88.   
  89.         if (0==strcmp(recv_buf,"quit"))  
  90.         {  
  91.             perror("the server is terminted by client\n");  
  92.             close(sockfd);  
  93.             return 0;  
  94.               
  95.               
  96.         }  
  97.   
  98.     }  
  99.   
  100.       
  101.       
  102. }  
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>


#define PORT 8900


int main()
{

	int sockfd;
	struct sockaddr_in server;
	struct sockaddr_in client;
	char send_buf[2048];
	char recv_buf[2048];
	int length;
	int sendnum;
	int recvnum;
	int port;


	port = PORT;
	int opt = SO_REUSEADDR;
	


/*The first stage:initnial phase*/

/*1.1 generating socket  phrahse*/

	if (-1==(sockfd=socket(AF_INET,SOCK_DGRAM,0)))
	{
		perror("error in generate socket\n");
		exit(1);

	}

	#ifdef DEBUG
		printf("the sokcet id is %d\n",sockfd);
		printf("enter binding phrase....\n");
	#endif
	setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

/*1.2 binding the socket*/

	memset(&server,0,sizeof(struct sockaddr));
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = htonl(INADDR_ANY);
	server.sin_port = htons(port);

	if (-1==bind(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr)))
	{
		perror("error in binding phrase\n");
		close(sockfd);
		exit(1);

	}


	#ifdef DEBUG
		printf("leaving binding phrase\n");
		printf("entering data exchange phrase\n");
	#endif

	length = sizeof(struct sockaddr_in); 

/* The Second Stage: data exchange phrase */
	while(1)
	{
		memset(&send_buf,0,sizeof(send_buf));
		memset(&recv_buf,0,sizeof(recv_buf));
        
  		/* receive the data from the client*/

		recvnum=recvfrom(sockfd,recv_buf,sizeof(recv_buf),0,(struct sockaddr*)&client,&length);
	
		recv_buf[recvnum]='\0';
		printf("the message from the client is %s:\n",recv_buf);
	

		sendnum = sprintf(send_buf,"hello,the guest from %s",inet_ntoa(client.sin_addr));
		sendto(sockfd,send_buf,sendnum,0,(struct sockaddr*)&client,sizeof(struct sockaddr));

		if (0==strcmp(recv_buf,"quit"))
		{
			perror("the server is terminted by client\n");
			close(sockfd);
			return 0;
			
			
		}

	}

	
	
}


udpclient.c

  1. #include<stdlib.h>   
  2. #include<stdio.h>   
  3. #include<string.h>   
  4. #include<sys/types.h>   
  5. #include<sys/socket.h>   
  6. #include<netinet/in.h>   
  7. #include<netdb.h>   
  8.   
  9.   
  10. void print_usage(char* str)  
  11. {  
  12.     printf("the command %s usage is:\n",str);  
  13.     printf("%s Ip_Address [port] \n");  
  14.   
  15. }  
  16.   
  17.   
  18.   
  19.   
  20. int main(int argc,char**argv)  
  21. {  
  22.   
  23.     int sockfd;  
  24.     struct sockaddr_in server;  
  25.     struct sockaddr_in reply;  
  26.     char send_buf[2048];  
  27.     char recv_buf[2048];  
  28.     int length;  
  29.     int sendnum;  
  30.     int recvnum;  
  31.     int port;  
  32.   
  33.     port =  atoi(argv[2]);  
  34.   
  35.   
  36.     if ((2>argc) ||(argc>3))  
  37.     {  
  38.         print_usage(argv[0]);  
  39.         exit(1);  
  40.   
  41.   
  42.     }  
  43.   
  44. /*The first stage:initnial phase*/  
  45.   
  46. /*1.1 generating socket  phrahse*/  
  47.   
  48.     if (-1==(sockfd=socket(AF_INET,SOCK_DGRAM,0)))  
  49.     {  
  50.         perror("error in generate socket\n");  
  51.         exit(1);  
  52.   
  53.     }  
  54.   
  55.     #ifdef DEBUG   
  56.         printf("the sokcet id is %d\n",sockfd);  
  57.         printf("enter data exchange  phrase....\n");  
  58.     #endif   
  59.   
  60. /*1.2 setting the destinate address */  
  61.   
  62.     memset(&server,0,sizeof(struct sockaddr));  
  63.     server.sin_family = AF_INET;  
  64.     server.sin_addr.s_addr = inet_addr(argv[1]);  
  65.     server.sin_port = htons(port);  
  66.   
  67.   
  68. /* The Second Stage: data exchange phrase */  
  69.       
  70.     memset(&send_buf,0,sizeof(send_buf));  
  71.     memset(&recv_buf,0,sizeof(recv_buf));  
  72.   
  73.     printf("what words do you want to tell to server:\n");  
  74.     gets(send_buf);  
  75.       
  76.           
  77.     /* send  the data to the server*/  
  78.       
  79.     sendnum = strlen(send_buf);  
  80.     if(0>sendto(sockfd,send_buf,sendnum,0,(struct sockaddr*)&server,sizeof(struct sockaddr)))  
  81.     {  
  82.         perror("send data error\n");  
  83.         close(sockfd);  
  84.         exit(0);  
  85.     }  
  86.       
  87.     recvnum = recvfrom(sockfd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&server,&length);  
  88.       
  89.     if (0>recvnum)  
  90.     {  
  91.           
  92.         perror("receive data error\n");  
  93.         close(sockfd);  
  94.         exit(0);  
  95.     }     
  96.   
  97.     recv_buf[recvnum]='\0';  
  98.     printf("the message from the server is :%s\n",recv_buf);  
  99.   
  100.     close(sockfd);  
  101.     exit(0);  
  102. }  
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>


void print_usage(char* str)
{
	printf("the command %s usage is:\n",str);
	printf("%s Ip_Address [port] \n");

}




int main(int argc,char**argv)
{

	int sockfd;
	struct sockaddr_in server;
	struct sockaddr_in reply;
	char send_buf[2048];
	char recv_buf[2048];
	int length;
	int sendnum;
	int recvnum;
	int port;

	port =	atoi(argv[2]);


	if ((2>argc) ||(argc>3))
	{
		print_usage(argv[0]);
		exit(1);


	}

/*The first stage:initnial phase*/

/*1.1 generating socket  phrahse*/

	if (-1==(sockfd=socket(AF_INET,SOCK_DGRAM,0)))
	{
		perror("error in generate socket\n");
		exit(1);

	}

	#ifdef DEBUG
		printf("the sokcet id is %d\n",sockfd);
		printf("enter data exchange  phrase....\n");
	#endif

/*1.2 setting the destinate address */

	memset(&server,0,sizeof(struct sockaddr));
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = inet_addr(argv[1]);
	server.sin_port = htons(port);


/* The Second Stage: data exchange phrase */
	
	memset(&send_buf,0,sizeof(send_buf));
	memset(&recv_buf,0,sizeof(recv_buf));

	printf("what words do you want to tell to server:\n");
	gets(send_buf);
	
        
  	/* send  the data to the server*/
	
	sendnum = strlen(send_buf);
	if(0>sendto(sockfd,send_buf,sendnum,0,(struct sockaddr*)&server,sizeof(struct sockaddr)))
	{
		perror("send data error\n");
		close(sockfd);
		exit(0);
	}
	
	recvnum = recvfrom(sockfd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&server,&length);
	
	if (0>recvnum)
	{
		
		perror("receive data error\n");
		close(sockfd);
		exit(0);
	}	

	recv_buf[recvnum]='\0';
	printf("the message from the server is :%s\n",recv_buf);

	close(sockfd);
	exit(0);
}

以上即完成了簡單的udp程序。另一個tcp程序在此處下載。同樣比較簡單,不解釋!

在文章後面說一下大小端(big endian於little endian)的問題吧,相信大家都知道大小端到底使什麼東西,這裏也不多說,現在要提到的是如何如何編程實現判斷所用機器是大端機器還是小端機器。我們知道,在C語言中,union中的字段是“共享內存”的,在一個union結構中,它的大小取決於其字段中最大的那個並且與之相等。其實想到這兒相信大家都已經知道了怎麼來判斷機器的大小端了,沒錯,就是使用union類型的特點進行判斷。現在就基於C中的union寫一個判斷機器是大小端的程序。如下:

  1. #include<stdio.h>   
  2.   
  3. union Nate  
  4. {  
  5.     unsigned short s;  
  6.     char cs[2];  
  7. }nate;  
  8.   
  9. void main()  
  10. {  
  11.     nate.s = 1;  
  12.     printf("nate.s is : %x\n",nate.s);  
  13.     printf("nate.cs[0] is : %d\n",nate.cs[0]);  
  14.     printf("nate.cs[1] is : %d\n",nate.cs[1]);  
  15.     if(nate.cs[0] == 1)  
  16.     {  
  17.         printf("little endian!\n");  
  18.     }  
  19.     else if(nate.cs[0] == 0)  
  20.     {  
  21.         printf("big endian!\n");  
  22.     }  
  23. }  
#include<stdio.h>

union Nate
{
	unsigned short s;
	char cs[2];
}nate;

void main()
{
	nate.s = 1;
	printf("nate.s is : %x\n",nate.s);
	printf("nate.cs[0] is : %d\n",nate.cs[0]);
	printf("nate.cs[1] is : %d\n",nate.cs[1]);
	if(nate.cs[0] == 1)
	{
		printf("little endian!\n");
	}
	else if(nate.cs[0] == 0)
	{
		printf("big endian!\n");
	}
}

在gcc中編譯運行程序即可看到本機器是大端還是小端了!這可以說是使用C中union的特性的一個好的應用,對於理解C中union類型也不錯!

文中包含程序在此處可以下載:http://download.csdn.net/detail/Natepan/3636259

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章