linux TCP简单编程学习总结

        TCP提供了一种可靠的,复杂的,面向连接的服务,通过三段式握手过程建立连接,用4个分组交换序列终止连接。当建立连接时,它将从将从状态机制的CLOSED状态转换成ESTABLISHED状态,当终止连接时,它又返回到CLOSED状态。

简单并发处理示例

客户端代码:

#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是没有用的,它的关闭不影响父进程的执行。

注意:在每次使用完套接字后最好养成关闭它的习惯,因为一个进程保留下不必要的文件描述字不仅没有意义,还会产生安全隐患。

 

你可能感兴趣的:(编程,linux,tcp,socket,struct,Stream)