客户端代码:
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 80
void str_cli(FILE *,int);
main(int argc,char **argv)
{
int sockfd,ret,len;
struct sockaddr_in ser_addr;
char *myname;
struct hostent *sh;
struct in_addr **addrs;
sh=gethostbyname("localhost");
if(sh==NULL){
printf("error when gethostbyname\n");
exit(0);
}
addrs=(struct in_addr **)sh->h_addr_list;
for(;*addrs!=NULL;addrs++){
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0){
printf("Error in socket\n");
exit(1);
}
ser_addr.sin_family=AF_INET;
ser_addr.sin_port=htons(20001);
memcpy(&ser_addr.sin_addr,*addrs,sizeof(struct in_addr));
bzero(ser_addr.sin_zero,8);
ret=connect(sockfd,(struct sockaddr *)&ser_addr,sizeof(struct sockaddr));
if(ret==0){
break;
}
else{
printf("error connecting\n");
close(sockfd);
}
}
if(*addrs==NULL){
printf("can't get connected with server\n");
exit(0);
}
str_cli(stdin,sockfd);
exit(0);
}
void str_cli(FILE *fp,int sockfd)
{
char sends[MAXSIZE],recvs[MAXSIZE];
int n=0;
while(fgets(sends,MAXSIZE,fp)!=NULL){
send(sockfd,sends,strlen(sends),0);
sleep(3);
if((n=recv(sockfd,recvs,MAXSIZE,0))==0){
printf("error receiving data\n");
exit(1);
}
recvs[n]=0;
fputs(recvs,stdout);
}
}
服务器端代码:
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#define MAXSIZE 80
#define MYPORT 20001
#define BACKLOG 10
#define BUFSIZE 100
void str_ser(int sockfd);
main()
{
int sockfd,new_fd,numbytes,ret;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
socklen_t sin_size;
char *buf;
pid_t pid;
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0){
printf("error in socket\n");
exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
bzero(&(my_addr.sin_zero),8);
ret=bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr));
if(ret<0){
printf("error in binding\n");
exit(1);
}
ret=listen(sockfd,BACKLOG);
if(ret<0){
printf("error in listening\n");
exit(1);
}
while(1){
sin_size=(socklen_t)sizeof(struct sockaddr_in);
new_fd=accept(sockfd,(struct sockaddr *)&their_addr,&sin_size);
if((pid=fork())==0){
close(sockfd);
str_ser(new_fd);
close(new_fd);
exit(0);
}
else{
printf("parent PID=%d,new_fd***=%d\n",getpid(),new_fd);
close(new_fd);
}
if(new_fd<0){
printf("error in accpet\n");
exit(1);
}
printf("***************************\n");
}
close(sockfd);
exit(0);
}
void str_ser(int sockfd)
{
char recvs[MAXSIZE];
int n=0;
while(1){
if((n=recv(sockfd,recvs,MAXSIZE,0))==0){
return ;
}
memcpy(recvs,"luoweishitiancai",MAXSIZE);
printf("recvs=%s\n",recvs);
send(sockfd,recvs,17,0);
}
}
说明:
首先运行server端代码,然后client代码运行,在输入一段字母后,server会返回一段字符给子进程,可以开多个client进行测试。
通过在服务器端对每一个请求folk一个子进程来处理,从而提高了处理的效率,在folk所在的语句后,要注意先关掉父进程的socket,因为folk语句将复制父进程的信息,而在子进行中父进程的socket是没有用的,它的关闭不影响父进程的执行。
注意:在每次使用完套接字后最好养成关闭它的习惯,因为一个进程保留下不必要的文件描述字不仅没有意义,还会产生安全隐患。