找回密码
 注册
查看: 694|回复: 8

关于通讯编程

[复制链接]
发表于 2005-5-13 10:36:34 | 显示全部楼层 |阅读模式
现在我想用c编一个程序,程序的要求是:
有个CLIENT,
有个SERVER
现在我想在CLIENT上发信息给SERVER,SERVER在把这个信息回给CLIENT

程序要求如上,但是我现在没有什么思路,这个是不是涉及到SOCKET编程啊
望高手给我点思路好吗?
发表于 2005-5-13 10:50:11 | 显示全部楼层
参考linux下面echo服务器的实现。
回复

使用道具 举报

发表于 2005-5-19 14:33:52 | 显示全部楼层
那个就是要socket的,网上的这方面的只是比较多
回复

使用道具 举报

发表于 2005-5-19 20:44:59 | 显示全部楼层
代码在这,不过是服务端发给客户端的,
服务端程序:
/***************************************************************************
                          severce.c  -  description
                             -------------------
    begin                : ¶þ  5ÔÂ 17 2005
    copyright            : (C) 2005 by hhuzhang
    email                :
***************************************************************************/

/***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include "mytcp.h"

#define SEND_PORT         80
#define SEND_FILE          "/uc/res"
#define READ_BUFSIZE       1

int ack_func(int sockfd, int ack);
void send_pthread(int socketfd);

int main(void)
{
  struct sockaddr_in  client_addr,my_addr;
  int local_fd,tmp_fd, Listen_sockfd,Sn_sockfd;
  int cl_len,order;
  int recv_bits,send_bits;
  int i;
  pthread_t pth_id;
  packet_frame  wr_packet;
  char read_buf[READ_BUFSIZE];

  order = 0;
  
  if ( (local_fd = open(SEND_FILE, O_RDONLY))<0 )
  {
    printf("open file error\n");
    exit(1);
  }

  if ( (tmp_fd = creat("/uc/temp", O_RDWR))<0 )
  {
    printf("creat tmpfile error\n");
    exit(1);
  }
  
  while (1)
  {
    for ( i=0;i<8;i++)
    {
      if ( read(local_fd, read_buf, sizeof(read_buf))<=0 )
        break;
  
      wr_packet.msg = read_buf[0];
    }

    if( i<8 )
    {
      memset( wr_packet.msg, 0, (8-i) );
      wr_packet.packet_order = order;
      if ( write( tmp_fd, &wr_packet, sizeof(wr_packet))<0 )
      {
        printf("write tmpfile error1\n");
        exit(1);
      }

      break;
    }

    wr_packet.packet_order = order++;
    if ( write( tmp_fd, &wr_packet, sizeof(wr_packet))<0 )
    {
      printf("write tmpfile error\n");
      exit(1);
    }
  }
  
  my_addr.sin_family = AF_INET;
  my_addr.sin_port = htons(IPPORT_USERRESERVED+SEND_PORT);
  my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  bzero(my_addr.sin_zero,;
  
  if ( (Listen_sockfd = socket(AF_INET, SOCK_STREAM, 0))<0 )
  {
    printf("open socket error\n");
    exit(1);
  }
  printf("listening ...\n");
  
  bind(Listen_sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
  
    if ( listen(Listen_sockfd, 10)<0 )
    {
      printf("listen error\n");
      exit(1);
    }
   
    while(1)
    {
      cl_len = sizeof(struct sockaddr);   
      if ( (Sn_sockfd=accept(Listen_sockfd, (struct sockaddr *)&client_addr, &cl_len))<0 )
      {        
        printf("can not get a connection\n");
        exit(1);
      }

      pthread_create(&pth_id, NULL, (void *)send_pthread, &Sn_sockfd);
         
    }

  close(Listen_sockfd);

  exit(0);
}

int ack_func(int sockfd, int ack)
{
  int i;

  recv(sockfd, &ack, 4, 0);
  for(i=0;i<5&&(ack!=1001);i++)
    recv(sockfd, &ack, 4, 0);

  if ( i==5 )
    return 0;

  else
    return 1;
}  

void send_pthread(int socketfd)
{
  FILE *tmp_fp;
  packet_frame  send_packet;
  int resnd_flag,client_ack;

  resnd_flag = 0;

  if ( (tmp_fp = fopen("/uc/temp", "r")) == NULL )
  {
    printf("fopen error\n");
    pthread_exit(NULL);
  }

  while ( fread(&send_packet, sizeof(send_packet), 1, tmp_fp) == 1 )
  {
    if ( send(socketfd, &send_packet, sizeof(send_packet), 0)<0 )
    {
      printf("send error,lost a packet\n");
      continue;
    }

    while ( !ack_func(socketfd, client_ack) )
    {
      send(socketfd, &send_packet, 8, 0);
      if ( resnd_flag>5 )
      {
        printf("communication halt,something wrong in networks\n");
        close(socketfd);
      
        exit(1);
      }

      resnd_flag++;
    }
  }

  fclose(tmp_fp);
  close(socketfd);
  pthread_exit(NULL);
}
   
客户端程序:

/***************************************************************************
                          client.c  -  description
                             -------------------
    begin                : ¶þ  5ÔÂ 17 2005
    copyright            : (C) 2005 by hhuzhang
    email                :
***************************************************************************/

/***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netdb.h>
#include "mytcp.h"

#define DES_IP    "192.168.1.4"
#define DES_PORT  80
#define DES_PATH  "/uc/recvfile"

int main(void)
{
   struct sockaddr_in sevcaddr,clntaddr;
   int clnsockfd,des_fd;
   char recv_buf[8];
   int ack,ret;
   packet_frame  recv_packet;

   ack = 1001;

   if ( (des_fd = creat(DES_PATH, O_WRONLY))<0 )
   {
     printf("creat recvfile error\n");
     exit(1);
   }

    if ( (clnsockfd = socket(AF_INET, SOCK_STREAM, 0))<0 )
    {
     printf("open socket error\n");
     exit(1);
    }
   
   sevcaddr.sin_family = AF_INET;
   sevcaddr.sin_port = htons(IPPORT_USERRESERVED+DES_PORT);
   sevcaddr.sin_addr.s_addr = inet_addr(DES_IP);
   bzero(&(sevcaddr.sin_zero), ;
   

    printf("connecting ...\n");
    ret = connect(clnsockfd, (struct sockaddr *)&sevcaddr, sizeof(struct sockaddr));

   while ( ret==-1 )
   {
     close(clnsockfd);
     sleep(2);
     printf("trying agian......\n");
     clnsockfd=socket(AF_INET, SOCK_STREAM, 0);
     ret=connect(clnsockfd, (struct sockaddr *)&clntaddr, sizeof(struct sockaddr));

     if ( ret==0 )
      break;
    }

   printf("connect successful\n");
   
   while( recv(clnsockfd, &recv_packet, sizeof(recv_packet), 0)>0 )
   {
     memcpy(recv_buf, recv_packet.msg, sizeof(recv_buf));
     
     if ( write(des_fd, recv_buf, sizeof(recv_buf))<0 )
     {
       printf("lost a packet when write file\n");
       continue;
     }
     
     if ( send(clnsockfd, &ack, 4, 0)<0 )
     {
       printf("send ack error,a packet lost\n");
       continue;
     }
     
   }

   shutdown(clnsockfd, 1);
   close(clnsockfd);
   exit(0);
}
回复

使用道具 举报

发表于 2005-5-19 21:23:33 | 显示全部楼层
tcp echo 服务。。。在 xinetd 里面包含的内置服务之一吧,呵呵。
回复

使用道具 举报

发表于 2005-5-21 12:04:32 | 显示全部楼层
现在我想在CLIENT上发信息给SERVER,SERVER在把这个信息回给CLIENT

你没有说是本机的两个程序还是不同机,靠网络传输的.
如果是本机的就用命名管道,消息队列等....
不然就socket咯
回复

使用道具 举报

发表于 2005-5-21 21:26:47 | 显示全部楼层
他说了是client,server,就应该是socket了,

我试过用新开的线程发送,但是send函数报错,不知道是怎么回事,

在linux中还是用进程的好,线程的优势在linux下几乎丧失殆尽了,方而缺点

突出来了,所以最好别用,新开一个进程,物理地址是共享的,逻辑地址是

拷贝一份的,所以切换时的工作量不是很大
回复

使用道具 举报

发表于 2005-5-21 22:20:21 | 显示全部楼层
在linux中还是用进程的好,线程的优势在linux下几乎丧失殆尽了,方而缺点

突出来了,所以最好别用


理论依据何在?

新开一个进程,物理地址是共享的,逻辑地址是

拷贝一份的,所以切换时的工作量不是很大


COW 而已。一旦一个进程有对内存的写入操作,将会导致复制操作。
回复

使用道具 举报

发表于 2005-5-22 08:31:39 | 显示全部楼层
一,linux中新建一个进程的效率本身就很高,很大程度上弥补了进程对线程的缺点

二,在编写多线程的时候,一旦出现时间上的偏差或共享了不该共享的变量,极又可能造成不良后果

三,调试一个多线程的程序比调试一个多进程的程序要复杂的多

四,在实践中,你仔细去测试,linux中的线程切换并不比进程切换开销小多少,在linu中新建的线程其实和新建的进程差不多,两者很相似。

五,对客户来说,人家才管你是线程还是进程呢,只要好用,你既然线程和进程
实现的效果都一样,干嘛不用进程呢?况且调试上简单。

以上观点基于linux系统下,在WINDOWS和UNIX系统中不成立
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2025-2-8 14:58 , Processed in 0.083927 second(s), 16 queries .

© 2001-2025 Discuz! Team. Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表