网络编程
网络编程,其实也是一种通信方式,前面我们学习的管道,消息队列,共享内存,信号,信号量,都是单机通信,也就是只能在一台电脑跑,而网络编程就可以实现多机通信,我们只需要知道ip地址,端口,socket,就可以进行通信。
socket连接协议
int socket(int domain, int type, int protocol)
brief:创建服务端(客户端)的连接协议
param:domian,是你所使用的协议族,有AF_INET (ipv4)AF_INET6(ipv6)等,type,用那种通信协议,tcp(相当于打电话,我发过去,你接到了,我才能继续发),udp(相当于发短信,你需要发送大量数据,可以用,但它不保证消息是否可靠),protocol,用那种协议进行传输,0,根据type定义的协议,进行默认分配。
return:返回网络编程的标识符
bind绑定ip地址和端口号
int bind (int sockfd, const struct sockaddr * addr, socklen_t addrlen);
uint16_t htons(uint16_t hostshort);//小端字节序转换网络字节序
字节序:小端字节序意思就是,低位存在低地址,大端字节序的意思就是,高位存在低地址
int inet_aton(const char *cp, struct in_addr *inp);//ip地址是一个字符串格式,网络并不认识字符串格式,所以我们要进行转换成网络认识的格式
struct sockaddr_in {
kernel_sa_family_t sin_family; //再次设置socket 的协议族 be16 sin_port; //设置端口号,但是网络字节序是大端标识符,这里我的电脑是小端标识符,所以我还要用到htnos进行转换
struct in_addr sin_addr; //一个结构体用于绑定ip地址
}
brief:对服务端(客户端)进行绑定ip地址,和端口号
param:sockfd,对哪个网络进行绑定,addr,用这个结构体绑定ip地址,端口号,addrlen,绑定的字节
return:返回0绑定成功,-1绑定失败
listen监听网络连接
int listen(int sockfd, int backlog);
breif:用于监听网络的连接
param:sockfd,对这个网络进行监听,backlong,监听的个数
return:
accept接收连接
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
brief:监听到有人连接,accept就开始接收连接
param:sockfd,接收连接到这个网络,addr,可以打印客户端的ip地址,addrlen,打印的字节数
return:接收连接成功返回一个新的标识符,我们和客户端的通信,靠这个新的标识符,返回-1,接收连接失败
read/write接收/发送消息
服务端
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
void * handler(void * fd);
struct sockaddr_in server;
struct sockaddr_in client;
void main(int argc,char ** argv)
{
if(argc != 3)
{
perror("argc");
exit(-1);
}
int fd;
int bflag;
int lflag;
pthread_t t1;
//1.socket
fd = socket(AF_INET,SOCK_STREAM,0);
if(fd < 0)
{
printf("socket error!\n");
}
else
printf("socket succeed!\n");
//2.bind
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&server.sin_addr);
bflag = bind(fd,(struct sockaddr *)&server,sizeof(struct sockaddr_in));
if(bflag < 0)
printf("bind error!\n");
else
printf("bind succeed!\n");
//3.listen
lflag = listen(fd,5);
if(lflag < 0)
printf("listen error\n");
else
printf("listen succeed!\n");
//4.accept
int len = sizeof(struct sockaddr_in);
while(1)
{
int new_Fd = accept(fd,(struct sockaddr *)&client,&len);
if(new_Fd < 0)
{
printf("accept error\n");
}
else
{
pthread_create(&t1,NULL,handler,(void *)&new_Fd);
pthread_join(t1,NULL);
}
}
}
//5.read/write
void * handler(void * fd)
{
char wBuf[128]={'\0'};
char rBuf[128]={'\0'};
int ret;
printf("客户端:%s已接入\n",inet_ntoa(client.sin_addr));
while(1)
{
memset(rBuf,'\0',sizeof(rBuf)+1);
memset(wBuf,'\0',sizeof(rBuf)+1);
ret = read(*(int *)fd,rBuf,sizeof(rBuf)+1);
if(ret > 0)
{
printf("客户端:%s:%s\n",inet_ntoa(client.sin_addr),rBuf);
}
else if(ret < 0)
{
printf("未接收到来自:%s的消息\n",inet_ntoa(client.sin_addr));
}
if(!strncasecmp(rBuf,"quit",4))
{
break;
}
printf("请发送您的消息给客户端:%s:",inet_ntoa(client.sin_addr));
gets(wBuf);
write(*(int *)fd,wBuf,sizeof(wBuf)+1);
}
printf("客户端:%s已退出会话---\n",inet_ntoa(client.sin_addr));
close(*(int *)fd);
printf("退出的线程号:%ld\n",pthread_self());
pthread_exit(NULL);
}
客户端
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
int main(int argc,char **argv)
{
if(argc != 3)
{
printf("error");
exit(-1);
}
int fd;
int cFlag;
//1.socket
fd = socket(AF_INET,SOCK_STREAM,0);
if(fd < 0)
{
printf("socket error\n");
}
else
printf("socket succeed!\n");
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&server.sin_addr);
//2.connect
cFlag = connect(fd,(struct sockaddr*)&server,sizeof(struct sockaddr_in));
if(cFlag < 0)
printf("connect error!\n");
else
printf("connect succeed!\n");
//3.read/write
char wBuf[128]={'\0'};
char rBuf[128]={'\0'};
while(1)
{
memset(wBuf,'\0',sizeof(wBuf)+1);
memset(rBuf,'\0',sizeof(wBuf)+1);
printf("请输入您要发的消息:");
gets(wBuf);
write(fd,wBuf,sizeof(wBuf)+1);
printf("发送成功!\n");
read(fd,rBuf,sizeof(rBuf)+1);
printf("接收来自服务端:%s:%s\n",argv[1],rBuf);
if(!strncasecmp(rBuf,"quit",4))
{
break;
}
}
printf("已退出服务端---\n");
close(fd);
return 0;
}