socket编程之初体验

来源:互联网 发布:js中date对象的方法 编辑:程序博客网 时间:2024/05/01 13:56

  网络的Socket数据传输是一种特殊的I/O。常用的Socket类型有两种:流失Socket(SOCK_STREAM针对TCP服务)和数据报式(SOCK_DGRAGM针对UDP服务)

 下面介绍一些Socket编程相关数据类型定义

  1,结构类型struct sockaddr{

                             unsigned  short sa_family; /*地址族, AF_xxx */

                             char  sa_data[14];/*14字节的协议地址*/

                                 }

 

      结构类型:struct  sockaddr_in {

                                short int sin_family;

                                unsigned short int  sin_port;

                                struct  in_addr  sin_addr;

                                unsigned char sin_zero[8];//用bzero将其置0以保持与struct sockaddr 同样大小

                                 };

 2,Socket编程相关函数原型

   (1) 描述符

      int socket(int domain,  int type, int protocol );

   (2)绑定

      int bind( int sockfd, struct sockaddr *my_addr, int addrlen );

      注:my_addr.sin_port = 0;// 系统随机选择一个未被使用的端口号;

            my_addr.sin_addr.s_addr = INADDR_ANY;//填入本机IP地址;

   (3)建立连接

     int connect( int sockfd, struct sockaddr *serv_addr, int addrlen);

   (4)监听

     int listen( int sockfd, int backlog);//backlog 指定最大请求个数,默认20

    

     故服务器端通常按 socket(); bind(); listen();顺序进行函数调用

   (5)连接端口的服务请求

     int accept( int sockfd, void * addr, int *addrlen );

 

   (6)数据传输

     int send( int sockfd, const void *msg, int len, int flags );

     int recv(int sockfd, void *buf, int len, unsigned int flags);

 

   (7)利用数据报方式进行数据传输

    int  sendto ( int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen );

   /*to 表示目标地机的IP地址和端口号信息; tolen 常常被赋值为sizeof(struct sockaddr);*/

    int recvfrom(int sockfd, void *buf, int len, unisgned int lags, struct sockadrr *from, int *fromlen);

                                       

  (8)结束数据传输

   int shutdown(int sockfd, int how );

    /*how: 0,不允许继续接受数据

    *           1,不允许继续发送数据

   *            2,不允许继续发送和接受数据,均为允许则调用close()*/

    

    (9)域名服务相关函数

  struct hostent *gethostbyname(const char *name );

其中: struct hostent{

                     char *h_name;//主机的官方域名

                     char **h_aliases;//一个以NULL结尾的主机别名数组

                     int  h_addrtype;//返回的地址类型,在Internet环境下位AF-INET

                     int h_length;//地址的字节长度

                     char  **h_addr_list; //一个以0结尾的数组,包含该主机的所有地址

};

#define  h_addr  h_addr_list[0]   //在h-addr-list中的第一地址

 

3附上一下实例,服务器端向连接的客服端打印“Hello ,world!”

服务器端代码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>

#define  MYPORT 3490
#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("ERROR: socket");
  return 0;
 }
 
 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( struct sockaddr))) == -1 ){
  perror("ERROR:bind");
  return 1;
 }
 
 if( listen( sockfd, BACKLOG) == -1 ){
  perror("ERROR: listen");
  return 1;
 }
 
 while(1){
  sin_size = sizeof( struct sockaddr_in );
  if( (new_fd = accept(sockfd, (struct sockaddr *) &their_addr, &sin_size)) == -1 ){
   perror( "ERROR: accept" );
   continue;
  }
  printf( "server : got connection from %s", inet_ntoa( their_addr.sin_addr ) );
  if( !fork() ){
   if( send(new_fd, "Hello world!", 14, 0) == -1)
    perror("ERROR:send");
   close( new_fd );
   return 0;
  }
  close(new_fd);
  waitpid( -1, NULL, WNOHANG);
 }
}


客户端代码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>

#define  PORT 3490
#define  MAXDATASIZE 100

int
main( int argc, char *argv[] )
{
 int sockfd, numbytes;
 char buf[MAXDATASIZE];
 struct hostent *he;
 struct sockaddr_in their_addr;
 
 if( argc < 2 ){
  fprintf( stderr, "Usage: client hostIP/n" );
  return 1;
 }
 
/* if( (he = gethostbyname( argv[1])) == NULL ){
  perror( "ERROR: gethostbyname" );
  return -1;
 }*/
 
 if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
  perror( "ERROR: socket" );
  return -1;
 }

 their_addr.sin_family = AF_INET;
 their_addr.sin_port = htons( PORT );
 their_addr.sin_addr.s_addr = inet_addr( argv[1] );
// their_addr.sin_addr = *( (struct in_addr *)he->h_addr );
 bzero( &(their_addr.sin_zero), 8 );
 
 if( connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1 ){
  perror("ERROR: connect");
  return -1;
 }

 if( (numbytes = recv(sockfd, buf, MAXDATASIZE, 0)) == -1 ){
  perror("ERROR: recv");
  return -1;
 }
 buf[numbytes] = '/0';
 printf("Recived: %s", buf);
 close(sockfd);
 return 0;
}

makefile内容

all : server.o client.o

server.o : server.c

               gcc -o server.o server.c

client.o : client.c

               gcc -o client.o client.c

 

 

原创粉丝点击