UNIX環境編程學習筆記---------編程實例----自己寫的CS程序





/*
任務:書寫一個自己的CS模型的程序

任務分解:

1.先寫一個server程序
.定義一個套接字地址
.創建一個套接字
.把套接字地址與套接字相綁定
.把套接字置於listen狀態
.接受一個連接
.進行套接字讀寫


在書寫過程中遇到的問題:


1.對於 struct sockaddr_in 結構 成員認識不清楚,記不清


struct sockaddr_in {
sa_family_t    sin_family;     //地址族
in_port_t      sin_port;    //端口號
struct in_addr         sin_addr;
        };


2.對於


 #include <arpa/inet.h>


       int inet_pton(int af, const char *src, void *dst);



3.對於 htos()函數的使用


 #include <arpa/inet.h>


       uint32_t htonl(uint32_t hostlong);


       uint16_t htons(uint16_t hostshort);


       uint32_t ntohl(uint32_t netlong);


       uint16_t ntohs(uint16_t netshort);
4.socket函數的使用


#include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>


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


5.


  與socket有關的宏定義在 sys/socket.h 頭文件中。
  
  
6.


我能不能這樣理解:


一個套接字地址 在內核中擁有一個緩衝區空間  ????


把套接字對象與套接字地址相綁定相當於 給文件對象指定 inode 節點和磁盤塊。




7.對accept函數的使用


#include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>


       int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  
 
 
我們來看看:   爲什麼accept()函數需要三個參數??


從服務器套接字中找出那些連接請求的,把從中取出該客戶端的套接字地址,然後放入內核的該服務器端套接字的管理下。




*/




#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<fcntl.h>
#include<errno.h>


int main(void)
{
//定義一個IP地址
struct in_addr  ip;
struct sockaddr_in c_addr;
char p[16]="192.168.10.3"
uint32_t nip;
//定義一個端口號
int  port =8000;
 
 
//把字符串IP地址轉換爲二進制IP地址
 
inet_pton(AF_INET,p,&ip);
 
//把二進制的IP地址轉換成網絡字節序
 
uint32_t nip= htonl(ip);
 
 
 
 
//定義一個IPV4套接字地址
 
struct sockaddr_in   Sip;
Sip.sin_family=AF_INET;
Sip.sin_addr=nip;
Sip.sin_port=htons(port);
 
 
//定義套接字描述符
int s_fd;
int c_fd;



//在內存中開闢套接字讀寫緩衝區
 char buf[50]="hello everyone i am the first program";


 
//開始創建一個套接字
  /*
  我的疑惑: 
  創建套接字時應該如何選擇套接字 type ???
  記住: 套接字類型不同,所使用的傳輸協議就不同
  
  如果使用 TCP 協議 ,則套接字類型爲: SOCK_STREAM  
  
  
  */
 
  s_fd=socket(AF_INET,SOCK_STREAM,0);
  
  // 給套接字綁定地址
  
  bind(s_fd,(struct sockaddr *)&Sip;sizeof(Sip));
  
  //把該套接字置於listen狀態
  
  listen(s_fd,10);
  
  //接收連接請求
  
  c_fd=accept(s_fd,(struct sockaddr*)&c_addr,sizeof(c_addr));
  
 
 
 
// 下面開始套接字讀寫操作
 write(c_fd,buf,51);
 
 close(s_fd);
 
 
 return 0;
 
}










//下面我開始書寫客戶端程序


/*
任務: 開發客戶端程序

任務分解:
1.創建一個套接字
2.調用 connect()發起連接請求
3.進行套接字讀寫
4.









1.讓我們先看一下connect()函數 :


#include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>


       int connect(int sockfd, const struct sockaddr *addr,
                   socklen_t addrlen);




/*
DESCRIPTION
       The  connect()  system call connects the socket referred to by the file
       descriptor sockfd to the address specified by addr.  The addrlen  argu-
       ment  specifies the size of addr.  The format of the address in addr is
       determined by the address space of the socket sockfd; see socket(2) for
       further details.


       If  the socket sockfd is of type SOCK_DGRAM then addr is the address to
       which datagrams are sent by default, and the only  address  from  which
       datagrams  are  received.   If  the  socket  is  of type SOCK_STREAM or
       SOCK_SEQPACKET, this call attempts to make a connection to  the  socket
       that is bound to the address specified by addr.


       Generally, connection-based protocol sockets may successfully connect()
       only once; connectionless protocol sockets may use  connect()  multiple
       times to change their association.  Connectionless sockets may dissolve
       the association by connecting to an address with the  sa_family  member
       of sockaddr set to AF_UNSPEC (supported on Linux since kernel 2.2).


RETURN VALUE
       If  the connection or binding succeeds, zero is returned.  On error, -1
       is returned, and errno is set appropriately.
*/
  
  
2.




我的疑問:


客戶端的套接字沒有進行bind操作,是不是意味着 客戶端的套接字是沒有套接字地址信息的???

能打印出來嗎????    還是 在做connect操作是即把服務器的套接字地址進行了寫入操作了  ???


爲什麼沒有???





3.
#include <arpa/inet.h>


       int inet_pton(int af, const char *src, void *dst);


  
  
  
4.


#include <arpa/inet.h>


       uint32_t htonl(uint32_t hostlong);


       uint16_t htons(uint16_t hostshort);


       uint32_t ntohl(uint32_t netlong);


       uint16_t ntohs(uint16_t netshort);




*/






#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>


#include<stdio.h>
#include<stdlib.h>
#include<errno.h>


int main(void)
{

// 定義一個要連接的服務器的套接字

struct sockaddr_in   Svadd;
struct in_addr     svip;
char sip[16];
char *ip="127.0.0.1";

//define some file descriptor

int n_fd;
int cntval;
//define a buf which used to load the content sent to server

char buf[100];


Svadd.sin_family=AF_INET;
inet_pton(AF_INET,"127.0.0.1",svip);
Svadd.sin_addr=svip;
Svadd.sin_port=htos(8000);

n_fd=socket(AF_INET,SOCK_STREAM,0);


cntval=connect(n_fd,(struct sockaddr*)&Svadd,sizeof(Svadd));

read(n_fd,buf,60);

printf("the contentwhich is read from server :%s\n",buf);

close(n_fd);

return 0;





}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章