Linux C网络编程 ————5、线程安全编程
  TEZNKK3IfmPf 2023年11月14日 13 0

服务器端代码实现

#include<stdio.h>
#include<strings.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/time.h>
#include<stdlib.h>

#define PORT 1234
#define BACKLOG 5
#define MAXDATASIZE 1000

typedef struct CLIENT{
  int fd;   
  char* name;   
  struct sockaddr_in addr; /*client's address information*/
  char* data; 
}CLIENT; 
void process_cli(CLIENT *client,char* recvbuf,int len);/*process client's information*/
void savedata(char* recvbuf,int len,char* data);

int main()
{
  int i,maxi,maxfd,sockfd;
  int nready;/**/
  ssize_t n;
  fd_set rset,allset;
  int listenfd,connectfd;
  struct sockaddr_in server;
  CLIENT client[FD_SETSIZE];
  char recvbuf[MAXDATASIZE];
  int sin_size;
  /*creat a TCP socket*/
  if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)
  {
     perror("Creating socket failed.");
     exit(1);
  }
  
  int opt=SO_REUSEADDR;
  setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
  bzero(&server,sizeof(server));
  server.sin_family==AF_INET;
  server.sin_port=htons(PORT);
  server.sin_addr.s_addr=htonl(INADDR_ANY);
  if(bind(listenfd,(struct sockaddr *)&server,sizeof(struct sockaddr))==-1)
  {
     perror("Bind error.");
     exit(1);
  }
  if(listen(listenfd,BACKLOG)==-1){
    perror("listen() error\n");
    exit(1);
  }
  
  sin_size=sizeof(struct sockaddr_in);
  maxfd=listenfd;
  maxi=-1;
  for(i=0;i<FD_SETSIZE;i++)
  {
     client[i].fd=-1;/*put  the description =-1*/
  }
  FD_ZERO(&allset);/*empty*/
  FD_SET(listenfd,&allset);/*put the listenfd into the description collection*/

  while(1)
  {
    struct sockaddr_in addr;
    rset=allset;    
    nready=select(maxfd+1,&rset,NULL,NULL,NULL);/*call select()*/
    if(FD_ISSET(listenfd,&rset))
    {
/*new client connection*/ /*accept connection*/
    if((connectfd=accept(listenfd,(struct sockaddr *)&addr,&sin_size))==-1)
    {
       perror("accept() error\n");
       continue;
    }
/*put new fd to client*/
    for(i=0;i<FD_SETSIZE;i++)
    if(client[i].fd<0){
             client[i].fd=connectfd;
             client[i].name=(char*)malloc(sizeof(MAXDATASIZE));
             client[i].addr=addr;
             client[i].data=(char*)malloc(sizeof(MAXDATASIZE));;
             client[i].name[0]='\0';
             client[i].data[0]='\0';
             printf("You got a connection from %s.",inet_ntoa(client[i].addr.sin_addr));
             break;
    }
    if(i==FD_SETSIZE)/*max description size*/
       printf("too many clients\n");
    FD_SET(connectfd,&allset);/*put the connectfd into the description collection*/
    if(connectfd>maxfd)
       maxfd=connectfd;
    if(i>maxi) 
       maxi=i;
    if(--nready<=0)/*no more readable descriptiors*/
       continue;
    }

    for(i=0;i<=maxi;i++){/*check all clients for data*/
       if((sockfd=client[i].fd)<0)
          continue;
       if(FD_ISSET(sockfd,&rset)){
          if((n=recv(sockfd,recvbuf,MAXDATASIZE,0))==0)
          {/*connection closed by client*/
             close(sockfd);
             printf("Client(%s) closed connection.User's data:%s\n",client[i].name,client[i].data);
             FD_CLR(sockfd,&allset);/*delete*/
             client[i].fd=-1;
             free(client[i].name);
             free(client[i].data);
          }else
             process_cli(&client[i],recvbuf,n);
          if(--nready<=0)/*no more readable descriptiors*/
             break;
    }
   }
  }
 close(listenfd);/*close listenfd*/
}

void process_cli(CLIENT *client,char* recvbuf,int len)
{
    char sendbuf[MAXDATASIZE];
    recvbuf[len-1]='\0';
    if(strlen(client->name)==0){
       memcpy(client->name,recvbuf,len);/*copy and display*/
       printf("\nClient's name is %s.\n",client->name);
       return;
    }
/*recvieve client's data*/
    printf("Received client(%s) message: %s.\n",client->name,recvbuf);
    savedata(recvbuf,len,client->data);
 /*achieve reverse*/
    for(int il=0;il<len-1;il++){
       sendbuf[il]=recvbuf[len-il-2];
    }
   /*achieve jiami*/
   for(int i=0;i<len;i++)
   {
     if((sendbuf[i]>='a'&&sendbuf[i]<='z')||(sendbuf[i]>='A'&&sendbuf[i]<='Z'))
     {
	sendbuf[i]=sendbuf[i]+4;
	if((sendbuf[i]>'Z'&&sendbuf[i]<='Z'+4)||(sendbuf[i]>'z'))
	sendbuf[i]=sendbuf[i]-26;
     }  
   }		
    sendbuf[len-1]='\0';
    send(client->fd,sendbuf,strlen(sendbuf),0);
    printf("Reversed and encrypted client(%s) message:%s\n",client->name,sendbuf);
}

void savedata(char* recvbuf,int len,char* data)
{
  int start = strlen(data);
  for(int i=0;i<len;i++){
     data[start+i]=recvbuf[i];
  }
}

客户端代码实现

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 1234
#define MAXDATASIZE 100
void process(FILE *fp,int sockfd);
char* getMessage(char* sendline,int len,FILE* fp);
int main(int argc,char *argv[]){
	int sockfd;
	struct  hostent *he;
	struct sockaddr_in server;
	if (argc!=2){
		printf("Usage:%s<IP Address>\n",argv[0]);
		exit(1);
	}
	if((he=gethostbyname(argv[1]))==NULL){
		printf("gethostbyname() error\n");
		exit(1);
	}
	if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
		printf("socket() error\n");
		exit(1);
	}
	bzero(&server,sizeof(server));
	server.sin_family=AF_INET;
	server.sin_port=htons(PORT);
	server.sin_addr=*((struct in_addr *)he->h_addr);
	if(connect(sockfd,(struct sockaddr *)&server,sizeof(server))==-1){
		printf("connect() error\n");
		exit(1);
	}
	process(stdin,sockfd);
	close(sockfd);
}
void process(FILE *fp,int sockfd){
	char sendline[MAXDATASIZE],recvline[MAXDATASIZE];
	int num;
	printf("Connected to server.\n");
	printf("Input client's name:");
	if(fgets(sendline,MAXDATASIZE,fp)==NULL){
		printf("\nExit.\n");
		return;
	}
	send(sockfd,sendline,strlen(sendline),0);
	while(getMessage(sendline,MAXDATASIZE,fp)!=NULL){
		send(sockfd,sendline,strlen(sendline),0);
		if((num=recv(sockfd,recvline,MAXDATASIZE,0))==0){
			printf("Server terminated.\n");
			return;
		}
		recvline[num]='\0';
		printf("Server Message:%s\n",recvline);
	}
	printf("\nExit.\n");
}
char* getMessage(char* sendline,int len,FILE* fp){
	printf("Input string to server:");
	return(fgets(sendline,MAXDATASIZE,fp));
}	

运行示例

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月14日 0

暂无评论

推荐阅读
TEZNKK3IfmPf