`
envy2002
  • 浏览: 149523 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

linux下socket编程

阅读更多

     在Java里面进行socket编程是很容易的事情,为了更好地搞清楚socket运行机制,有必要了解一下linux下socket是如何运行的。由于涉及到底层的东西比较多,即使你本来很了解如何运用这些API,但究其下面层次的原理,如果不深入到源码的话,也是比较难以理解的。我本人理解的也不是很好,只能抛砖引玉了。

     

 

大概的流程如图所示:

 

1.服务器建立一个socket监听本机的某个端口(图中socket1)

 

        2.客户机建立一个socket去连接服务器监听端口(如图中socketA)

 

        3.服务器accept一个新的socket文件描述,表示服务器的某个进程要和某个IP的客户的某个进程进行通信了。

 

 

   两台机通信的充分必要条件是 : 协议,源IP地址,源端口(端口就是进程的标示), 目标IP地址,目标端口,总共5个要素。

 

     下面的代码主要展示的是单线程的聊天小程序。

 

     主要思想就是基于以上流程,但是添加了log日志功能。上源码:

 

 

 

/*
 provide the function to log.
 input: environment varibles, (1) LEVEL=DEBUG||WARNING||ERROE (2)LOGPATH(the log file saving path)
 output: different level log file
*/
#ifndef  _LOG_H_
#define  _LOG_H_

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>


//define the debug level
#define  DEBUG 5
#define  WARNNING 4
#define  ERROR 3
#define  WORKKING 1
//if return 0,means ok, !=0, means not ok.
int mylog(char * optional_msg,char * msg, int level);	

#endif
 
#include "log.h"

int mylog(char * optional_msg,char * msg, int level)
{
	char * pc_level=getenv("LEVEL");
	char * pc_path =getenv("LOGPATH");
	
	//configure debug level
	if(pc_level==NULL)	
	{	
		pc_level="WORKKING";
	}
	//printf("current level is  %s\n",pc_level);
		
	//configure path	
	char path[256];
	if(pc_path==NULL)
	{		
		getcwd(path, sizeof(path));
		//printf("current path is %s\n",path);
		pc_path=path;	
				
	}
	
	//printf("configured path is %s\n",pc_path);	
	
	int int_src=0;
	char *pc_preLog;
	if(strcmp(pc_level,"DEBUG")==0)
	{	
		int_src=5;
	  	pc_preLog="[DEBUG]  ";
	}
	if(strcmp(pc_level,"WARNNING")==0)
	{
		int_src=4;
		pc_preLog="[WARNNING]  ";
	}
	if(strcmp(pc_level,"ERROR")==0)
	{
		int_src=3;
		pc_preLog="[ERROR]  ";
	}
	if(strcmp(pc_level,"WORKKING")==0)
	{
		int_src=1;
		pc_preLog="[WORKKING]  ";
	}
	
	//create a file to write log.	
	char target_path[400];
	strcpy(target_path,pc_path);
	strcat(target_path,"/log.txt");
	//printf("target path is %s\n",target_path);
	
	
	if(int_src>=level)
	{
		int fileid=open(target_path,O_WRONLY|O_APPEND|O_CREAT,0);
		if(fileid<0)
		{
			printf("create log file failed!\n");
			exit(0);	
		}
		write(fileid,optional_msg,strlen(optional_msg));
		write(fileid,pc_preLog,strlen(pc_preLog));
		write(fileid,msg,strlen(msg));
		//set time
		time_t timep;
        time (&timep);
        write(fileid,"   ----",strlen("   ----"));
        write(fileid,ctime(&timep),strlen(ctime(&timep)));
        
		write(fileid,"  \n",strlen("  \n"));
		close(fileid);
    }
	return 0;
}  






 

 

#include "log.h"
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <signal.h>


#define BUFFER_SIZE 256

int client_socket_id=0;

void closeSocketId()
{
	mylog("[Server] ","close socket file id",DEBUG);
	close(client_socket_id);
	
	
}

void * receiveMsg(void * args)
{
	while(1)
	{	
		char buffer[BUFFER_SIZE]={0};
	    mylog("[Server] ","before receive.....",DEBUG);
		int recv_length=recv(client_socket_id,buffer,BUFFER_SIZE,0);
		mylog("[Server] ","after receive.....",DEBUG);
		if (recv_length <= 0)
	    {
	          mylog("[Server] ","error comes when recieve data from server!",DEBUG);
	          exit(0);
	          
	    }
	    
	    printf("from server:%s\n",buffer);
    }
	
	return NULL;
}

void closeSocket()
{
	mylog("[Server] "," positively close connection socket",DEBUG);
	close(client_socket_id);
	exit(0);	
}

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

//setup the sigint
    signal(SIGINT,closeSocket);
    
	struct sockaddr_in server_addr,client_addr;
	int size_of_addr=sizeof(server_addr);
	//printf("size of addr is %d\n",size_of_addr);
	
	//init server_addr;
	bzero(&server_addr,sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_port=htons(9999);
	server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
	char * pc;
	pc=inet_ntoa(server_addr.sin_addr);
	//printf("server11 ip is %s\n",pc);
	
	int socketid=0;
	
	//create socket file
	mylog("[Server] ","before create socket......",DEBUG);
	if((socketid=socket(AF_INET,SOCK_STREAM,0))<0)
		mylog("[Server] ","create socket error",DEBUG);
	mylog("[Server] ","after create socket......",DEBUG);	
	//bind
	if(bind(socketid,(struct sockaddr*)&server_addr,size_of_addr)<0)
		mylog("[Server] ","bind server address error",DEBUG);
	
	//listen
    mylog("[Server] ","before listen......",DEBUG);
    
	if(listen(socketid,5)<0)
		mylog("[Server] ","listen error",DEBUG);
		
	mylog("[Server] ","after listen......",DEBUG);	
	

	socklen_t client_length=sizeof(client_addr);
	mylog("[Server] ","before accept......",DEBUG);
	client_socket_id=accept(socketid,(struct sockaddr*)&client_addr,&client_length);
	mylog("[Server] ","after accept......",DEBUG);
	if(client_socket_id<0)
		mylog("[Server] "," client socket file id is negetive, worry",DEBUG);
		
	//set receive thead
	pthread_t pthread_id;
	pthread_id=pthread_create(&pthread_id,NULL,	receiveMsg,NULL);\
	
	char *pcwelcome="welcome\n";
	int length_string=strlen(pcwelcome);
	send(client_socket_id,pcwelcome,length_string,0);	
	
	while(1)
	{	
		char msg[BUFFER_SIZE];
		//scanf("%[^n]",msg);
		fgets(msg,BUFFER_SIZE,stdin);	

		int length_send=send(client_socket_id,msg,BUFFER_SIZE,0);
		//printf("send msg length is %d\n",length_send);
		if(length_send<0)
			printf("send worry\n");		
	}
	//close(client_socket_id);
	return 0;
}

 #include <stdio.h>

#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <signal.h>
#include "log.h"


#define BUFFER_SIZE 256

int socketid=0;
int client_result=0;
void * receiveMsg(void * args)
{
	while(1)
	{	
		if(client_result<0)
		{
			mylog("[Client] ","no connection",DEBUG);
			exit(0);	
		}
		char buffer[BUFFER_SIZE]={0};
	    mylog("[Client] ","before receive.....",DEBUG);
		int recv_length=recv(socketid,buffer,BUFFER_SIZE,0);
		mylog("[Client] ","after receive.....",DEBUG);
		if (recv_length <= 0)
	    {
	          mylog("[Client] ","error comes when recieve data from server!",DEBUG);
	          exit(0);
	         
	    }
	    
	    printf("from server:%s\n",buffer);
    }
	
	
}

void closeSocket()
{
	printf(" positively close connection socket\n");
	close(socketid);
	exit(0);	
}


int main(int argc, char ** argv)
{
	//setup the sigint
    signal(SIGINT,closeSocket);
    
	struct sockaddr_in server_addr,client_addr;
	int size_of_addr=sizeof(server_addr);
	//printf("size of addr is %d\n",size_of_addr);
	
	//init server_addr;
	bzero(&server_addr,sizeof(client_addr));
	client_addr.sin_family=AF_INET;
	//char* pc_port=argv[1];
	//printf("argv[1]   %s\n",pc_port);
	//int int_port=atoi(pc_port);
	//printf("int_port   %d\n",int_port);
	client_addr.sin_port=htons(9998);
	client_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
	char * pc;
	pc=inet_ntoa(client_addr.sin_addr);
	//printf("server ip is %s\n",pc);
	
	
	
	//create socket file
	if((socketid=socket(AF_INET,SOCK_STREAM,0))<0)
		mylog("[Client] ","create socket error",DEBUG);
		
	//bind
	if(bind(socketid,(struct sockaddr*)&client_addr,size_of_addr)<0)
	{	
		mylog("[Client] ","bind server address error",DEBUG);
		exit(0);
	}
	
	server_addr.sin_family=AF_INET;
	server_addr.sin_port=htons(9999);
	server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");	
	
	socklen_t server_length=sizeof(server_addr);
	client_result=connect(socketid,(struct sockaddr*)&server_addr,server_length);
	
	if(client_result<0)
		printf("connect failed\n");
		
	//set receive thead
	pthread_t pthread_id;
	pthread_id=pthread_create(&pthread_id,NULL,	receiveMsg,NULL);
	
	while(1)
	{	
		char msg[BUFFER_SIZE]={0};
		fgets(msg,BUFFER_SIZE,stdin);
		int messageLength=strlen(msg);
		//printf("message Length is %d\n",messageLength);
		int length_send=send(socketid,msg,messageLength,0);
		//printf("send msg length is %d\n",length_send);
		if(length_send<0)
			mylog("[Client] ","send worry",DEBUG);	
    }
    close(socketid);
	return 0;
	
}

 

   编译运行方法:

   1. 首先在自己的.profile里面设置环境变量export LEVEL=DEBUG,重启linux.LOGPATH不设置也可以,程序会给一个默认的,LEVEL当然也会,只有LEVEL=DEBUG的时候,log才会比较详细,log的等级嘛,像log4j,呵呵。

 

   2. 编译

 

     生成server.exe

gcc -Wall -g -lpthread log.h log.c server.c -o server.exe
 

     生成client.exe

 

       gcc -Wall -g -lpthread log.h log.c client.c -o client.exe

 

    3 .执行

     开一个终端

      ./server.exe

    开一个终端

     ./client.exe

 

   这一版写的比较粗糙,许多结构性设计的东西都是不合理的,比如mylog这个方法等等。等以后把多线程版本出了再修

该一下这个版本的。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics