Socket函数
1.包含头文件
2.功能:创建一个套接字用于通信
3.原型
int socket(int domain,int type,int protocol);
4.参数
domain:指定通信协议族
type:指定socket类型,流式套接字SOCK_STREAM(TCP),数据报套接字SOCK_DGRAM(UDP),原始套接字SOCK_RAM
protocol:协议类型
5.返回值:成功返回非负整数,它与文件描述符类似,我们把它称为套接字描述字,简称套接字。失败返回-1.
bind函数
1.包含头文件
2.绑定一个本地地址到套接字
3.原型:
int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
4.参数
sockfd:socket函数返回的套接字
addr:要绑定的地址
addrlen:地址长度
5.返回值:
成功返回0,失败返回-1
listen函数
1.包含头文件
2.功能:将套接字用于监听进入的连接
3.原型:
int listen(int sockfd,int backlog);
4.参数
sockfd:socket函数返回的套接字
backlog:规定内核为此套接字排队的最大连接个数
5.返回值:
成功返回0,失败返回-1
一般来说,listen函数应该在调用socket函数和bind函数之后,调用函数accept之前。
对于给定的监听套接口,内核要维护两个队列:
1.已由客户发出并到达服务器,服务器正在等待完成相应的TCP三路握手过程
2.已完成连接的队列
accept函数
1.包含头文件
2.功能:从已完成连接队列返回第一个连接,如果已经完成连接队列为空,则阻塞。
3.原型 int accept(int socked,struct sockaddr *addr,socklen_t *addrlen);
4.参数
sockfd:服务器套接字
addr:将返回对等方的套接字地址
addrlen:返回对等方的套接字地址长度
5.返回值:成功非负整数,失败返回-1;
服务器端:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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)
{
ERR_EXIT("socket");
}
/*if(listenfd = socket(PF_INET,SOCK_STREAM,0)<0)*/
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);
/*seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");*/
/*iner_aton("127.0.0.1",&servaddr.sin_addr);*/
/*设置地址重复利用*/
int on = 1;
if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) < 0)
{
ERR_EXIT("setsockopt");
}
/*绑定*/
if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0 )
{
ERR_EXIT("bind");
}
/*绑定监听*/
if(listen(listenfd,SOMAXCONN) < 0)
{
ERR_EXIT("listen");
}
struct sockaddr_in peeraddr; /*目标地址*/
socklen_t peerlen = sizeof(peeraddr);
int conn; /*已连接套接字*/
/*等待连接*/
if( (conn = accept(listenfd,(struct sockaddr*)&peeraddr,&peerlen)) < 0 )
{
ERR_EXIT("accept");
}
else
{
printf("ip = %s,port = %d\n",inet_ntoa(peeraddr.sin_addr),peeraddr.sin_port);
char recvbuf[1024];
while(1)
{
memset(recvbuf,0,sizeof(recvbuf));
int ret = read(conn,recvbuf,sizeof(recvbuf));
fputs(recvbuf,stdout);
write(conn,recvbuf,ret);
}
}
close(conn);
close(listenfd);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0); \
int main(void)
{
int sock;
char sendbuf[1024] = {0};
char recvbuf[1024] = {0};
if((sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
{
ERR_EXIT("socket");
}
/*if(listenfd = socket(PF_INET,SOCK_STREAM,0)<0)*/
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");
/*iner_aton("127.0.0.1",&servaddr.sin_addr);*/
if( connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
{
ERR_EXIT("connect");
}
else
{
printf("ip = %s,port = %d\n",inet_ntoa(servaddr.sin_addr),servaddr.sin_port);
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;
}
测试效果: