计算机网络学习socket--day2

1.TCP客户/服务器模型(C/S)

2.回射客户/服务器模型

3.socket、bind、listen、accept、connect
||--------------------------------------------------------------
socket函数
包含头文件<sys/socket.h>
功能:创建一个套接字用于通信
原型:
int socket(int domain,int type,int protocol);
参数:
domain:指定通信协议族(protocol family)
type:指定socket类型,流式套接字SOCK_STREAM,数据报套接字SOCK_DGRAM原始套接字SOCK_RAW
protocol:协议类型
返回值:
成功返回非负整数,它与文件描述符类似,我们把它称为套接口描述字,简称套接字。失败返回-1。

man socket 查看帮助

||---------------------------------------------------------------
bind函数
包含头文件<sys/socket.h>
功能:绑定一个本地地址到套接字
原型:
int bind(int socket,const struct sockaddr *addr,socklen_t addrlen);
参数:
sockfd:socket函数返回的套接字
addr:要绑定的地址
addrlen:地址长度
返回值:成功返回0,失败返回-1

||---------------------------------------------------------------
listen函数
包含头文件<sys/socket.h>
功能:将套接字用于监听进入的连接
原型:
int listen(int sockfd,int backlog);
参数:
sockfd:socket函数返回的套接字
backlog:规定内核为此套接字排队的最大连接个数
返回值:成功返回0,失败返回-1
****
1.一般来说,listen函数应该在调用socket和bind函数之后,调用函数accept之前调用。
2.对于给定的监听套接口,内核要维护两个队列
1》已有客户发出并到达服务器,服务器正在等待完成相应的TCP三路握手过程
2》已完成连接的队列
||---------------------------------------------------------------
accept函数
man 2 accept
包含头文件<sys/socket.h>
功能:从已完成连接队列返回第一个连接,如果已完成连接队列为空,则阻塞。
原型:
int accept(int sockfd,struct sockaddr *addr, socklen_t *addrlen);
参数:
sockfd:服务器套接字
addr:将返回对等方的套接字地址
addrlen:返回对等方的套接字地址长度
返回值:成功返回非负整数,失败返回-1
||---------------------------------------------------------------
被动套接字
用来接收连接的, accept
主动套接字
用来发起连接的,connet
||---------------------------------------------------------------
connect函数
包含头文件<sys/socket.h>
功能:建立一个连接至addr所指定的套接字
原型:
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
参数:
sockfd:未连接套接字
addr:要连接的套接字地址
addrlen:第二个参数addr长度
返回值:成功返回0,失败返回-1
||---------------------------------------------------------------

实现一个回射服务器,客服端不断从标准输入获取一行数据发送给服务器端,服务器端接收并且把它回射回去

#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet.in.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>

#define ERR_EXIT(m)
do
{
perror(m);
exit(EXIT_FAILURE);
}while(0)

int main(void)
{
int listenfd;
if((listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
/*同上一样表示listenfd = socket(PF_INET, SOCK_STREAM, 0);*/
ERR_EXIT("socket");
/*55-61地址的初始化*/
struct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(5188);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
/*servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");*/
/*inet_aton("127.0.0.1",&servaddr.sin_addr);*/

//绑定
if (bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))) < 0
ERR_EXIT("bind"); //绑定失败
//监听 查看man 2 listen
if(listen(listenfd, SOMAXCONM) < 0)
ERR_EXIT("listen");
//接受
struct sockaddr_in peeraddr;
socklen_t peerlen = sizeof(peeraddr); //peerlen必须有初始值
int coon; //成为主动套接字在下面的if后
if((coon = accept(listen,(struct sockaddr*)&peeraddr,&peerlen)) < 0)
ERR_EXIT("accept");

char recvbuf[1024];
while(1)
{
memset(recvbuf, 0, sizeof(recvbuf));
int ret = read(conn, recvbuf, sizeof(recvbuf));
fputs(recvbuf, stdout);
write(conn, recvbuf,ret);
//write(conn, recvbuf,strlen(recvbuf))

}

close(conn);
close(listenfd);
return 0;
}


实现一个回射客户端

#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet.in.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>

#define ERR_EXIT(m)
do
{
perror(m);
exit(EXIT_FAILURE);
}while(0)

int main(void)
{
int sock;
if((listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
ERR_EXIT("socket");
struct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(5188);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

if(connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
ERR_EXIT("connect");
char sendbuf[1024] = {0};
char recvbuf[1024] = {0};
while(fgets(sendbuf,sizeof(sendbuf),stdin) != NULL)
{
write(sock,sendbuf,strlen(sendbuf));
read(sock,recvbuf,sizeof(recvbuf));

fputs(recvbuf,stdout);
memset(sendbuf,0,sizeof(sendbuf));
memset(recvbuf,0,sizeof(recvbuf));
}

close(sock);//关闭套接口

return 0;
}

posted @ 2019-05-05 22:49  我不叫庄子  阅读(182)  评论(0编辑  收藏  举报