痛苦的想死,太复杂了,还是记录几个简单的玩具代码吧,这些例子都出自head first c.
-
#include <apue.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
-
int main(int argc, char*argv[])
-
{
-
char *advice[]={
-
"Take smaller bites\r\n",
-
"Go for the tight jeans. No they do NOT make you look fat.\r\n",
-
"One word: inappropriate\r\n",
-
"Just for today, be honest. Tell your boss what you *really* think\r\n",
-
"You might want to rethink that haircut\r\n"
-
};
-
int listener_d=socket(PF_INET,SOCK_STREAM,0);
-
-
if(argc!=2)
-
{
-
printf("%s <port>\n",argv[0]);
-
exit(1);
-
}
-
-
struct sockaddr_in name;
-
name.sin_family=PF_INET;
-
name.sin_addr.s_addr=htonl(INADDR_ANY);
-
name.sin_port=(in_port_t)htons(atoi(argv[1]));
-
-
int reuse=1;
-
if(setsockopt(listener_d,SOL_SOCKET,SO_REUSEADDR,(char *)&reuse,sizeof(int))==-1)
-
fputs("setsockopt() error\n",stderr);
-
-
-
if(bind(listener_d,(struct sockaddr*)&name,sizeof(name))==-1)
-
fputs("bind() error\n",stderr);
-
-
listen(listener_d,10);
-
puts("Waiting for connection");
-
-
while(1){
-
struct sockaddr_storage client_addr;
-
unsigned int address_size=sizeof(client_addr);
-
int connect_d=accept(listener_d,(struct sockaddr*)&client_addr,&address_size);
-
char *msg=advice[rand() % 5];
-
-
send(connect_d,msg,strlen(msg),0);
-
close(connect_d);
-
}
-
return 0;
-
}
第一个例子比较简单,第二个多几个自定义函数,加上了信号的处理。
-
#include <apue.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <errno.h>
-
-
int listener_d;
-
-
void handle_shutdonw(int sig);
-
int catch_signal(int sig,void(*handler)(int));
-
int open_listener_socket();
-
void bind_to_port(int socket,int port);
-
int say(int socket,char *s);
-
void error(char *msg);
-
int read_in(int socket,char *buf,int len);
-
-
int read_in(int socket,char *buf,int len)
-
{
-
char *s=buf;
-
int slen=len;
-
int c=recv(socket,s,slen,0);
-
while((c>0)&&(s[c-1]!='\n')){
-
s+=c;
-
slen-=c;
-
c=recv(socket,s,slen,0);
-
}
-
if(c<0) //incase there is an error
-
return c;
-
else if(c==0)
-
buf[0]='\0'; //nothing read,send back an empty string
-
else
-
s[c-1]='\0';
-
return len-slen;
-
}
-
-
void handle_shutdown(int sig)
-
{
-
if(listener_d)
-
close(listener_d);
-
-
fprintf(stderr,"Bye!\n");
-
exit(0);
-
}
-
-
int catch_signal(int sig,void(*handler)(int))
-
{
-
struct sigaction action;
-
action.sa_handler=handler;
-
sigemptyset(&action.sa_mask);
-
action.sa_flags=0;
-
return sigaction(sig,&action,NULL);
-
}
-
-
int open_listener_socket()
-
{
-
int s=socket(PF_INET,SOCK_STREAM,0);
-
if(s==-1)
-
error("can't not open socket");
-
-
return s;
-
}
-
-
void bind_to_port(int socket,int port)
-
{
-
struct sockaddr_in name;
-
name.sin_family=PF_INET;
-
name.sin_addr.s_addr=htonl(INADDR_ANY);
-
name.sin_port=(in_port_t)htons(port);
-
int reuse=1;
-
if(setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,(char*)&reuse,sizeof(int))==-1)
-
error("can't set the reuse option on the socket");
-
-
int c=bind(socket,(struct sockaddr*)&name,sizeof(name));
-
if(c==-1){
-
error("Can't bind to socket");
-
}
-
}
-
-
int say(int socket,char *s) //send a string to a client
-
{
-
int result=send(socket,s,strlen(s),0);
-
if(result==-1)
-
fprintf(stderr,"%s: %s\n","Error talking to the client",strerror(errno));
-
return result;
-
}
-
-
void error(char *msg)
-
{
-
fprintf(stderr,"%s: %s\n",msg,strerror(errno));
-
exit(1);
-
}
-
-
-
-
int main(int argc, char *argv[])
-
{
-
if(argc!=2){
-
fprintf(stderr,"%s <port>",argv[0]);
-
exit(1);
-
}
-
-
if(catch_signal(SIGINT,handle_shutdown)==-1)
-
error("can't set the interrupt handler");
-
-
listener_d=open_listener_socket();
-
int port=atoi(argv[1]);
-
bind_to_port(listener_d,port);
-
if(listen(listener_d,10)==01)
-
error("can't listen");
-
-
struct sockaddr_storage client_addr;
-
unsigned int address_size=sizeof(client_addr);
-
puts("Waiting for connection");
-
char buf[255];
-
-
while(1)
-
{
-
int connect_d=accept(listener_d,(struct sockaddr*)&client_addr,&address_size);
-
if(connect_d==-1)
-
error("Can't open secondary socket");
-
-
if(say(connect_d,"Internet Knock-Knock Protocol Server\r\nVersion 1.0\r\nKnock!Knock!\r\n>")!=-1)
-
{
-
read_in(connect_d,buf,sizeof(buf));
-
-
if(strncasecmp("Who's there?",buf,12))
-
say(connect_d,"You should say 'Who's ther?'!");
-
else{
-
if(say(connect_d,"Osca\r\n> ")!=-1){
-
read_in(connect_d,buf,sizeof(buf));
-
if(strncasecmp("Oscar who?",buf,10))
-
say(connect_d,"You should say 'Oscar who?'!\r\n");
-
else
-
say(connect_d,"Oscar silly question,you get a silly answer\r\n");
-
}
-
}
-
}
-
close(connect_d);
-
}
-
return 0;
-
}
第三个例子则增加了一个fork() 和wait() ,即多进程的模型。
-
#include <apue.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <errno.h>
-
-
int listener_d;
-
-
void handle_shutdonw(int sig);
-
int catch_signal(int sig,void(*handler)(int));
-
int open_listener_socket();
-
void bind_to_port(int socket,int port);
-
int say(int socket,char *s);
-
void error(char *msg);
-
int read_in(int socket,char *buf,int len);
-
-
int read_in(int socket,char *buf,int len)
-
{
-
char *s=buf;
-
int slen=len;
-
int c=recv(socket,s,slen,0);
-
while((c>0)&&(s[c-1]!='\n')){
-
s+=c;
-
slen-=c;
-
c=recv(socket,s,slen,0);
-
}
-
if(c<0) //incase there is an error
-
return c;
-
else if(c==0)
-
buf[0]='\0'; //nothing read,send back an empty string
-
else
-
s[c-1]='\0';
-
return len-slen;
-
}
-
-
void handle_shutdown(int sig)
-
{
-
if(listener_d)
-
close(listener_d);
-
-
fprintf(stderr,"Bye!\n");
-
exit(0);
-
}
-
-
int catch_signal(int sig,void(*handler)(int))
-
{
-
struct sigaction action;
-
action.sa_handler=handler;
-
sigemptyset(&action.sa_mask);
-
action.sa_flags=0;
-
return sigaction(sig,&action,NULL);
-
}
-
-
int open_listener_socket()
-
{
-
int s=socket(PF_INET,SOCK_STREAM,0);
-
if(s==-1)
-
error("can't not open socket");
-
-
return s;
-
}
-
-
void bind_to_port(int socket,int port)
-
{
-
struct sockaddr_in name;
-
name.sin_family=PF_INET;
-
name.sin_addr.s_addr=htonl(INADDR_ANY);
-
name.sin_port=(in_port_t)htons(port);
-
int reuse=1;
-
if(setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,(char*)&reuse,sizeof(int))==-1)
-
error("can't set the reuse option on the socket");
-
-
int c=bind(socket,(struct sockaddr*)&name,sizeof(name));
-
if(c==-1){
-
error("Can't bind to socket");
-
}
-
}
-
-
int say(int socket,char *s) //send a string to a client
-
{
-
int result=send(socket,s,strlen(s),0);
-
if(result==-1)
-
fprintf(stderr,"%s: %s\n","Error talking to the client",strerror(errno));
-
return result;
-
}
-
-
void error(char *msg)
-
{
-
fprintf(stderr,"%s: %s\n",msg,strerror(errno));
-
exit(1);
-
}
-
-
-
-
int main(int argc, char *argv[])
-
{
-
if(argc!=2){
-
fprintf(stderr,"%s <port>",argv[0]);
-
exit(1);
-
}
-
-
if(catch_signal(SIGINT,handle_shutdown)==-1)
-
error("can't set the interrupt handler");
-
-
listener_d=open_listener_socket();
-
int port=atoi(argv[1]);
-
bind_to_port(listener_d,port);
-
if(listen(listener_d,10)==01)
-
error("can't listen");
-
-
struct sockaddr_storage client_addr;
-
unsigned int address_size=sizeof(client_addr);
-
puts("Waiting for connection");
-
char buf[255];
-
-
while(1)
-
{
-
int connect_d=accept(listener_d,(struct sockaddr*)&client_addr,&address_size);
-
if(connect_d==-1)
-
error("Can't open secondary socket");
-
-
if(fork()==0){ //child process
-
close(listener_d);
-
if(say(connect_d,"Internet Knock-Knock Protocol Server\r\nVersion 1.0\r\nKnock!Knock!\r\n>")!=-1)
-
{
-
read_in(connect_d,buf,sizeof(buf));
-
-
if(strncasecmp("Who's there?",buf,12))
-
say(connect_d,"You should say 'Who's ther?'!");
-
else{
-
if(say(connect_d,"Osca\r\n> ")!=-1){
-
read_in(connect_d,buf,sizeof(buf));
-
if(strncasecmp("Oscar who?",buf,10))
-
say(connect_d,"You should say 'Oscar who?'!\r\n");
-
else
-
say(connect_d,"Oscar silly question,you get a silly answer\r\n");
-
}
-
}
-
}
-
close(connect_d);
-
exit(0);
-
}
-
//wait(NULL);
-
close(connect_d);
-
}
-
return 0;
-
}
#wait(NULL)是我自己加上去的,为了不产生zombie进程。否者只有主进程退出,子进程才会被init进程发现。
倒是让我想起来以前用nagios,经常会有zombie 进程的产生,估计是主进程少了waitpid 或者wait。除非主进程退出,zombie进程才会被init回收。
阅读(1311) | 评论(0) | 转发(0) |