Chinaunix首页 | 论坛 | 博客
  • 博客访问: 124504
  • 博文数量: 70
  • 博客积分: 2510
  • 博客等级: 少校
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-24 18:53
文章分类
文章存档

2015年(8)

2014年(14)

2011年(1)

2010年(21)

2009年(26)

我的朋友

分类: 系统运维

2009-12-10 11:02:03

//客户端:
//从命令行读入服务器的IP地址;并连接到服务器;
//循环从命令行读入一行字符串,并传递给服务器,由服务器对字符串反转,并将结果返回客户程序;
//客户程序显示反转后的字符串;

#include
#include
#include
#include
#include
#include
#include
#define PORT 2088
#define MAXLINE 100
int main(int argc, char *argv[])
{
int   fd,n;
char sendline[MAXLINE],recvline[MAXLINE];
struct hostent * he;
struct sockaddr_in server;
if (argc != 2)
{
   printf("Usage: %s \n", argv[0]);
   exit(1);
}
//获取主机名
if ((he = gethostbyname(argv[1])) == NULL) {
   perror("gethostbyname error.");
   exit(1);
}
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
   perror("Create socket failed.");
   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);//inet_pton(AF_INET,argv[1],&server.sin_addr);也行
//连接到服务器
if (connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)
{
   perror("connect failed!");
   exit(1);
}
else printf("Connect Success!\n");
//输入客户name,服务器显示
printf("Input your name:");
if(fgets(sendline,MAXLINE,stdin)!=NULL)
write(fd,sendline,strlen(sendline));

//循环从命令行读入一行字符串,并发送到服务器
printf("Input a string:");   
while((fgets(sendline,MAXLINE,stdin))!=NULL)
{  
   //发送数据到服务器
   write(fd,sendline,strlen(sendline));
   //接收从服务器发来的数据
   if((n=recv(fd,recvline,MAXLINE,0))==0)
       {
    perror("server terminated prematurely!");
    return;
   }
   recvline[n]='\0';
   printf("recieve data from server:%s\n",recvline);
   printf("Input a string:");
   //fputs(recvline,stdout);
}

//关闭fd
close(fd);
exit(0);
}

//服务器端:

//服务器等待客户连接,连接成功后显示客户地址,接着接收该客户的名字并显示,然后接收来自客户的信息(字符串),将该字符串反转,
//并将结果送回客户。要求服务器具有同时处理多个客户的能力。当某个客户断开连接时,打印所有该客户输入的数据。
#include
#include
#include
#include
#include
#include
#include

#include
#include
#include
#include
#include
#include
#define MAXSIZE 100
#define PORT 2088
#define BACKLOG 10
static void* doit(void *arg);//线程执行函数
void process_cli(int connectfd,struct sockaddr_in client);//处理函数 call by doit()
void savedata_r(char *recvbuf ,int len,char *savebuf);
struct ARG
{
int connfd;
struct sockaddr_in client;
};

static pthread_key_t key;
static pthread_once_t once=PTHREAD_ONCE_INIT;
static void destructor(void * ptr)
{
free(ptr);
}
static void getkey_once(void)
{
//创建键,通过key指针返回,destructor所指函数将由为该键存放过某个值的每个线程在终止时调用
pthread_key_create(&key,destructor);
}

typedef struct INDEX
{
int index;
}TSD_INDEX;


int main(void)
{
int listenfd,connectfd;
//pid_t pid;
struct sockaddr_in server,client;
int client_len;

pthread_t tid;
struct ARG *arg;
//创建监听套接字
if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
   perror("Create socket failed");
   exit(0);
}

//初始化地址结构
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(0);
}
//监听
if(listen(listenfd,BACKLOG)==-1)
{
   perror("listen error");
   exit(0);
}
client_len=sizeof(struct sockaddr);
while(1)
{
   //接收
   if((connectfd=accept(listenfd,(struct sockaddr *)&client,&client_len))==-1)
   {
    perror("accept error");
    exit(0);
   }
   arg=(struct ARG *)malloc(sizeof(struct ARG));
   if(arg==NULL) printf("malloc failed!\n");
   arg->connfd=connectfd;
   memcpy((void *)&arg->client,(void *)&client,sizeof(struct sockaddr_in));
   //创建线程为客户服务
   if(pthread_create(&tid,NULL,&doit,(void *)arg)>0)
         {
          perror("pthread_creat() error");
          free(arg);
          continue;
         }
}
//关闭监听
close(listenfd);
}

static void *doit(void *arg)
{
struct ARG *info;
info=(struct ARG *)arg;
process_cli(info->connfd,info->client);
free(arg);
pthread_exit(NULL);
}
void process_cli(int connectfd,struct sockaddr_in client){
int recNumber;
char buff[MAXSIZE],temp[MAXSIZE],cli_name[MAXSIZE],savebuf[MAXSIZE];

printf("Connect from %s, port is %d \n",inet_ntop(AF_INET,&client.sin_addr,buff,sizeof(buff)),ntohs(client.sin_port));
//显示connected client name
if((recNumber=read(connectfd,cli_name,MAXSIZE))>0)
{
   cli_name[recNumber-1]='\0';
   printf("Client's name is:%s\n",cli_name);
}
      else
{
   close(connectfd);
   printf("client disconnected.\n");
   return;
        }
//将接收到的string,首位倒置并发送client
while((recNumber=read(connectfd,buff,MAXSIZE))>0)
{
   savedata_r(buff,recNumber,savebuf);
   buff[recNumber] = '\0';
   printf("Received client (%s) message: %s\n", cli_name, buff);
  
   for(int i=0;i         {
    temp[i]=buff[recNumber-i-2];
         }
   temp[recNumber-1]='\0';
       write(connectfd,temp,recNumber-1);  
}
printf("all of data from client (%s): %s\n",cli_name,savebuf);
//关闭连接
close(connectfd);
}


void savedata_r(char *recvbuf ,int len,char *savebuf)
{
TSD_INDEX *data;
pthread_once(&once,getkey_once);
//获取键关联的值
if((data=(TSD_INDEX *)pthread_getspecific(key))==NULL)
{
   data=(TSD_INDEX *)calloc(1,sizeof(TSD_INDEX));// 清零
   pthread_setspecific(key,data);//存放键关联的值-- tsd的指针
   data->index=0;
}
for(int k=0;ksavebuf[data->index++]=recvbuf[k];
savebuf[data->index]=0;
}

阅读(777) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-09-19 11:31:18

请问客户端如何实现输入quit退出?

chinaunix网友2009-12-18 23:50:05

这位兄弟,最近部门在针对合适人选内部推荐,这次机会较好,真诚希望你或者这里的朋友能关注下: ------------------------------------------------------------------------------------------- 全球TOP3通信公司创新项目招募人才(机会较好,待遇从优) 地点:上海   包括但不限于以下方面:(1)嵌入式技术和linux开发(2)编译环境开发(3)应用和业务软件开发(4)浏览器和互联网技术(5)媒体平台:媒体技术和算法(6)通信协议:传输,组网以及协议开发等   招聘范围:中高级技术专家,技术带头人,3年以上工作经验   待遇:从优,只要您有实力,待遇一切可谈   关于我们:提供一个良好的技术和开发环境,提供优越的个人发展空间通道以及完善的培训制度,个人配股激励计划。   若有任何疑问或者兴趣,欢迎邮件:BlankHt@163.com   静候您或者您的朋友回音。