- 浏览: 153821 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
lanhaitun1991:
亲,其实你这里介绍的方法有一个最大的问题:如果放入队列之后,但 ...
分布式事务 -
lp385267935:
不错 很好用~3Q
jsonlib json-->object,忽略object中没有的属性 -
xiebo1983:
http://www.sqkoo.com/show/detai ...
mysql latin1乱码 -
envy2002:
当然可以了,tomcat中源码你可以看看,只要“欺骗”过去to ...
tomcat中的长连接 -
newSaa:
问一下,可以在 tomcat 建立tcp 长连接吗?
tomcat中的长连接
在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这个方法等等。等以后把多线程版本出了再修
该一下这个版本的。
发表评论
-
tomcat停止
2012-04-18 12:50 0#!/bin/sh #kill tomcat pid ... -
ubuntu 装mysql
2012-04-12 13:37 775最近项目好急,没时间整理,特做以下记录 去mysql网 ... -
red hat 安装svn
2012-03-23 16:34 1346素材: httpd-2.2.22.tar subve ... -
linux 当前shell指定java版本
2012-02-16 09:41 2923装了red hat 5.4,系统默认自带了Java 1.4, ... -
U盘安装red hat.
2012-02-09 10:50 1051没有DVD光盘和DVD光驱,悲剧啊,还好,网上有工具。 ... -
linux 下samba使用简介
2011-12-06 16:46 1119今天装了一台真正的linux主机(red hat),呵呵。安装 ... -
Shell学习
2011-11-30 17:32 764类unix操作系统中有b shell, k shell, c ... -
gdb调试linux0.11内核。
2011-11-26 16:13 16011. 下载bochs源码,配置,编译。 ./con ... -
red hat的远程桌面 xmanager
2011-11-04 14:49 3047用virtualbox装好red hat之后,我们可 ... -
virtual box中安装red hat并实现 ftp功能
2011-11-03 15:49 1753由于在公司上网,公司有个防火墙,安装虚拟主机需要虚 ... -
bochs调试linux 0.11内核
2011-07-01 15:24 6787学习操作系统,最难的就是 ... -
关于linux程序在内存中的分布管理
2011-05-27 10:54 1721这段时间,一直在看汇编,想学习一下li ... -
solaris mount细节
2011-04-11 14:33 10121. 首先确保 nfs server ... -
linux file open的实质
2011-03-30 17:36 2082linux open file的时候到底做了什么呢 ... -
linux-gcc 编译时头文件和库文件搜索路径(转)
2011-03-11 11:16 1721一、头文件 gcc 在编译时寻找所需要的头文件 : ※ ... -
linux extern关键字的作用2
2011-03-09 17:13 1504extern int O_RDONLY; #includ ... -
GCC 参数详解(转载)
2011-03-01 10:29 1145gcc and g++分别是gnu的c &am ... -
linux extern关键字的作用
2011-02-25 17:28 2943extern 的作用是起到一个 ... -
linux 可执行文件依赖库查看
2011-02-25 12:24 5687在多线程编程中,我们用gcc -Wall -g ... -
c语言编译全过程(转)
2011-02-25 10:46 1226C语言编译全 ...
相关推荐
在IT领域,Linux下的Socket编程是一项基础且重要的技能,它涉及到网络通信的核心技术。这篇博客“Linux下Socket编程”很可能会深入探讨如何在Linux操作系统环境下使用Socket接口进行网络编程,这是构建服务器端和...
### Linux下Socket编程基础详解 #### 一、引言 在深入探讨Socket编程之前,我们首先需要理解什么是Socket。在计算机网络中,Socket是应用程序与网络通信之间的一个接口,它提供了一种方式来建立网络连接并进行数据...
免费分享一下关于Linux下socket编程的基本原理和相关函数的解析,还有一下其他的体会,如有不对的地方请指正。
本篇主要讲解Linux下Socket编程的基本概念、步骤和示例,包括客户端和服务器端的实现。 一、Socket基本概念 Socket,又称为套接字,是网络通信中的一个抽象概念,它代表了两台机器间的一个通信链路的两端。Socket...
Linux下Socket编程 - aobai219的专栏 - CSDN博客Linux下Socket编程 - aobai219的专栏 - CSDN博客
下面详细解释在Linux环境下进行Socket编程的一些关键知识点。 首先,Socket API中最基本的函数是创建套接字的socket()函数,其原型为: ```c int socket(int domain, int type, int protocol); ``` 这里的domain...