服务器
编程流程:
- int socket() 创建一个socket
返回值:出错返回-1 成功返回socket文件描述符 - int bind() 命名绑定,确定IP+port 只有在命名之后客户端才知道如何连接它
返回值:失败返回-1 成功返回0
进行绑定步骤时要进行主机字节序和网络字节序的转换和IP地址点分十进制的字符串类型和整型值之间的转换 - int listen() 启动监听 ,socket命名绑定了之后还不能马上接受客户的链接,需要先启动监听来创建一个监听队列用于存放待处理的客户链接,连接队列的大小最好设置为5
- int accept() 与客户端建立连接
返回值:每进行一次连接若失败则返回-1,若成功则会返回一个新的文件描述符,该文件描述符唯一的标识了被连接的服务端。 - recv()/send() 发送接收消息,若客户端不发送消息整个进程会阻塞在recv,只要客户端有输入 返回值一定为1
- connect() 客户端向服务器发送请求链接的申请
- close() 关闭文件描述符断开连接
服务器:
socket() bind() listen() while{ accept() recv()/send() close() }
客户端:
socket() connect() send()/recv() close()
tcp服务器
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
/*服务器端*///思考?:怎样做到多个客户端同时发送消息
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建监听套接字
if( sockfd == -1)
{
return 0;
}
struct sockaddr_in saddr,caddr;//服务器ip,port, 客户端的ip,port(套接字地址)
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);//1024知名端口,4096保留端口,大于4096临时端口
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");//测试地址。inet_addr()将字符串转化成无符号整形-》//初始化完成
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//绑定,命名套接字
if(res == -1)
{
printf("连接服务器失败\n");
return 0;
}
res = listen(sockfd,5);//linux 5 指的是监听已完成三次握手的监听队列的大小
assert( res != -1);
while(1)
{
int len = sizeof(caddr);
int c = accept(sockfd,(struct sockaddr*)&caddr,&len);//接受连接,可能阻塞
if(c<0)
{
continue;
}
printf("accept c=%d\n",c);//c连接套接字
while(1)
{
char buff[128]={0};
int n=recv(c,buff,127,0);//recv 接收 recv返回值==0说明对端关闭 <0说明错误
if( n == 0)
{
break;
}
printf("buff(%d)=%s\n",n,buff);
send(c,"ok",2,0);//send 发送
}
close(c);
printf("client close\n");
}
}
客户端
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
/*客户端*/
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建套接字
if( sockfd == -1)
{
printf("create socket err\n");
return 0;
}
//bind()可以绑定,但是一般不绑定
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if( res == -1 )
{
printf("bind err\n");
return 0;
}
while(1)
{
char buff[128]={0};
printf("input:\n");
fgets(buff,128,stdin);
if(strncmp(buff,"end",3)==0)
{
break;
}
send(sockfd,buff,strlen(buff),0);
memset(buff,0,128);
recv(sockfd,buff,127,0);
printf("buff=%s\n",buff);
}
close(sockfd);
}