C语言开发邮件系统-1

网络程序设计核心——socket接收发送信息(套接字)

server端——调用socket——bind函数——Client    server——accept函数——Client
Client端——调用socket——connect函数——Server主机——IP端口号 

#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain,int type,int protocol); 
/*
domain 协议簇设置为AF_INET(TCP/IP 协议簇),AF_UNIX(域协议簇),AF_ISO(协议簇); 
type 套接字类型(SOCK_STREAM流套,SOCK_DGRAM数据报套,SOCK_RAM原始套接字);
protocol可设置为0.
*/
int connect(int sockfd,struct sockaddr *servaddr,int addren);
/*sockfd返回的描述符,servaddr服务器地址、传输端口号及地址类型,addren地址长度*/

// Linux系统4个库函数的字节顺序转换:
#include<netinet/in.h>
unsigned long int htonl(unsigned long int hostlong);   
unsigned short int htons(unsigned short int hostshort);
unsigned long int ntohl(unsigned long int netlong);
unsigned short int ntohs(unsigned short int netshort);

int bind(int sockfd,struct sockaddr *my_addr,int addrlen);
/*描述符,指针包含名称端口与IP地址,地址长度*/

int listen(int sockfd,int backlog);//backlog指定连接请求队列最大长度,成功返回0,否则-1.

int accept(int sockfd,struct sockaddr *addr,int *addrlen);
/*描述符,套接字地址结构指针,长度,若对客户进程地址不感兴趣可将addr与addrlen设为NULL*/

int read(int fd,char *buf,int len); //buf是应用的发送缓冲区 成功返回字节数,0位关闭写管道,-1出错
int write(int fd,char *buf,int len); //buf是接收缓冲区

int rect(int sockfd,void *buf,int len,int flags); //与read相似 增加了读操作的控制
int send(int sockfd,void *buf,int len,int flags); //与write相似

#include<unistd.h>
int close(int sockfd); //成功返回0,失败返回-1,参考C语言中文网

//TCP套接字描述符
int sock_fd=socket(AF_INET,SOCK_STREAM,0);//成功返回描述符,调用失败则返回-1,下面的if语句用于判断。
if(sock_fd<0)
   {
     perror("socket creating error");
     exit(1); //进程退出会有一个返回值,1表示异常退出,0表示正常退出。
   }
//套接字地址:
struct sockaddr
  {
    unsigned short sa_family; //sa_family为协议簇地址类型
    char sa_date[14];         //14字节的协议地址,sa_data存储具体地址内容
   };
//每种协议簇定义自己的协议地址类型
struct in_addr 
  {
     _u32 s_addr;  //unsigned long 32比特的IP地址
   };
struct socketaddr_in 
   {
     short in sin_family;            //地址类型
     unsigned short int sin_port;    //端口号
     struct in_addr sin_addr;        //Internet地址
     unsigned char _pad[_SOCK_SIZE-sizeof(short int)-sizeof(unsigned short int)-sizeof(struct in_addr)];//填充比特
    };//编写TCP与UDP代码时,通常使用struct sockaddr_in结构来赋值

//connect()函数用法:
  struct socketaddr_in serv_addr;
  int ret,sock_fd;
  bzero(&serv_addr,sizeof(struct,sockaddr_in)); //套接字清零,包含'\0'。2008标准已没有该函数,可用memset()代替,是对结构体与数组清零最快方法。
  serv_addr.sin_family=AF_INET;
  serv_addr.sin_port=htons(SERVER_PORT);
  ret=inet_aton("127.0.0.1",&serv_addr.sin_addr); //参考arpa/inet.h 将一个字符串IP地址转换为一个32位的网络序列IP地址,即带“点”的地址。
  if(ret<0)
    {
      perror("convert IP address error"); //转换IP地址错误
      exit(1);
     }
  ret=connect(sock_fd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr_in));
  if(ret<0)
    {
      perror("connect to server error");
      exit(1); 
     }

//bind()函数用法:
struct sockaddr_in serv_addr;
bzero(&serv_addr,sizeof(struct sockaddr_in));
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERVER_PORT);
serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); //INADDR_ANY指任何网络设备接口
ret=(bind(sock_fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
if(ret<0)
 {
   perror("bind to SERVER_PORT error");
   exit(1);
  }
/*
实现由服务器向客户端发送字符串“Hello World!”
服务器代码如下:
*/
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/type.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/wait.h>
#define MYPORT 4050
#define BACKLOG 10

int main()
 {
    int sockfd,new_fd;
    struct sockaddr_in my_addr; //有问题吧?
    struct sockaddr_in their_addr;
    int sin_size;

    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
      {
        perror("socket");
        exit(1);
       }
    else
       {
         printf("socket created successfully!\n");
       }
       
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(MYPORT);
    my_addr.sin_addr.s_addr=INADDR_ANY;
    bzero(&(my_addr.sin_zero),8);
    
    if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(structaddr))==-1)
     {
       perror("bindB");
       exit(1);
      }
    else
      printf("address binded sucessfully!\n");
     
     if(listen(sockfd,BACKLOG)==-1)
       {
         perror("listen");
         exit(1);
       }
    else
      printf("start listening the clients' connect request ……\n");

    while(1)
      {
        sin_size=sizeof(struct sockaddr_in);
        if((new_fd=accept(sockfd,(struct sockaddr*)&their_addr,&sin_size))==-1)
         {
           perror("accept");
           exit(1);
         }
        else
         printf("server.got connection from %s\n",inet_ntoa(their_addr.sin_addr));
           if(!fork())
             if(send(new_fd,"Hello World!\n",14,0)==-1)
               {
                 perror("send");
                 close(new_fd);
                 exit(0);
                }
         close(new_fd);
       }
     while(waitpid(-1,NULL,WNOHANG)>0);
   }
/*
客户端程序
*/
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/type.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/wait.h>
#define MAXDATASIZE 100

int main(int argc.char **argv)
 {
   int sockfd,numbytes,servport;
   struct sockaddr in servaddr;
   char buf[[MAXDATESIZE];
   if(argc !=3)
     {
       fprintf(stderr,"usage:hellocli <server's ip address> <server's port>");
       exit(1);
      }
         
   sockfd=socket(AF_INET,SOCK_STREAM,0);
   bzero(&servaddr,sizeof(struct sockaddr_in));
   servaddr.sin_family=AF_INET;
   servaddr.sin_port=htons(atoi(argv[2]));
   inet_aton(argv[1],&servaddr.sin_addr);
   connect(sockfd,(struct sockaddr*)&servaddr,sizeof(struct sockaddr));
   if(numbytes=recv(sockfd,buff,MAXDATESIZE,0))==-1)
     {
       perror("recv");
       exit(1);
      }
   buf[numbytes]='\0';
   printf("Receive from server %s:\n %s",argv[1],buf);
   printf("totally %d bytes received\n\n",numbytes);
   close(sockfd);
   printf("……local socket closed\n"); 
   return 0;
  }

参考:

SOCKET.H 头文件:  http://pubs.opengroup.org/onlinepubs/7908799/xns/syssocket.h.html

NETINET/IN.H 头文件:  http://pubs.opengroup.org/onlinepubs/7908799/xns/netinetin.h.html

ARPA/INET.H 头文件  http://pubs.opengroup.org/onlinepubs/7908799/xns/arpainet.h.html

C语言中文网:http://c.biancheng.net/cpp/html/229.html  

可清零的初始化函数:memset(void *s,int ch,size_t n);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值