/*
任务:书写一个自己的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;
}