基于TCP协议的socket通信(Linux)

         以下两个程序分别模拟了服务器端和客户端所做的动作: 服务器在和客户端建立连接后, 每1s向客户端发送字符串"a piece of message from server.", 客户端每1s接受一次数据, 并将接收到的数据显示到终端.

        我们必须考虑当服务器端先结束运行时, 客户端该做出怎么样的动作: 是继续接收空数据, 还是结束运行. 当然, 客户端应该结束运行, 那么该如何判断服务器端是否结束运行了呢? 在client.c中我加入了对接收数据的长度的判断, 当接收到的数据长度为0时, 那么就结束客户端的运行------这样一来, 客户端便可随服务器端程序的终止而终止了.

//server.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h> 
#include <unistd.h>
#define SERVPORT 3333
#define BACKLOG 10

int sockfd,client_fd;
int sin_size;
char buf[50] = "a piece of message from server.";

void send_message()//send pieces of message to host
{
    while(1)
     {
	  send(client_fd, buf, 32, 0);
	  sleep(1);
     }
}

int main()
{	
    struct sockaddr_in my_addr;    
    struct sockaddr_in remote_addr; 
    sockfd = socket(AF_INET, SOCK_STREAM, 0);//建立socket --
    my_addr.sin_family=AF_INET;//AF_INET地址族    
    my_addr.sin_port=htons(SERVPORT);//设定端口号(host -> networks)
    my_addr.sin_addr.s_addr = INADDR_ANY;//32位IPv4地址
    bzero(&(my_addr.sin_zero),8); //置前8个字节为0
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) 
     {
  	  perror("bind 出错!");		
	  exit(1);	
     }
    if (listen(sockfd, BACKLOG) == -1) //监听socket连接, 设置队列中最多拥有连接个数为10
     {	
	  perror("listen 出错!");	
          exit(1);     
     }
    while(1)
     {
	  sin_size = sizeof(struct sockaddr_in);//记录sockaddr_in结构体所占字节数
	  if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1) //accept()缺省是阻塞函数, 阻塞到有连接请求为止
          {	
	      perror("accept error");		
	      continue;		
	  }
	  printf("收到一个连接来自:  %s\n", inet_ntoa(remote_addr.sin_addr));
	  if (!fork())//son process 
          { 
	      send_message();
            close(client_fd);	
            exit(0);		
          }
	  else//father process 
	  {
	     close(client_fd);
  	  }
     }
} 

//client.c
#include<stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERVPORT 3333
#define MAXDATASIZE 100

int sockfd, recvbytes;
char buf[MAXDATASIZE];

void receive()//receive pieces of message from host
{
    while(1)
     {
	  recvbytes = recv(sockfd, buf, MAXDATASIZE,0);
	  if(recvbytes == 0)
	  {
		break;
	  }
	  buf[recvbytes] = '\0';//end flag
	  printf("%s\n", buf);
	  sleep(1);
     } 
}

int main(int argc, char *argv[])
{
    struct hostent *host;
    struct sockaddr_in serv_addr;
    if(argc < 2) 
     {
	  fprintf(stderr,"Please enter the server's hostname!\n");
	  exit(1);	
     }
    if((host=gethostbyname(argv[1]))==NULL)
     {
	  herror("gethostbyname error!");	
	  exit(1);	
     }
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)//建立socket
     { 
	  perror("socket create error!");	
	  exit(1);	
     }
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_port=htons(SERVPORT);
    serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
    bzero(&(serv_addr.sin_zero),8);
    if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) //请求连接
     {
	  perror("connect error!");
	  exit(1);
     }
    //successful connection
    receive();
    close(sockfd);//关闭连接
}

运行结果:

 

猜你喜欢

转载自blog.csdn.net/weixin_42048463/article/details/94713697