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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.