//套接字成对出现,要绑定ip和端口号, 插座 有两端 数据发送端 数据接收端
//ip地址+端口号 在网络环境中唯一标识一个进程,这个进程就叫套接字
//套接字是l中的一个伪文件
//socket 有一个文件描述符,在L中实现形式是:一个文件描述符对应两个文件缓冲区(r/w),全双工
//网络字节序:二进制 TCP/IP采用大端字节序,计算机中是小端存储
//数据包从网卡发送到网络环境中时,字节序发生变化,解包要读ip,所以要做网络字节序和主机字节序的转换
//htonl(长整形无符号数)转换ip 地址本地字节转换成网络字节的32位 host to net long
//htos()转换端口号
//对端发送过来的数据,我要从网络中读过来,读的时候也要进行转换
//ntohl()ip
//ntohs()端口号
//int inet_pton(int af, const char *src, void *dst ) p是点分十进制的字符串ip,在网络中传输要传输成网络字节序,用这个可以直接转换
// IP地址的形式:(AF_INET)ipv4/ipv6 点分十进制的字符串直接传进去,const只读 传出参数(泛型)
//inet_ntop(int af,const void *src, char*dst, socklen_t size )
// 字符串指针 字符串的大小
//sockaddr数据结构:(早期)struct sockaddr 用来描述ip地址协议的
//(发展)struct sockaddr_in
//注意:定义的时候用(发展)struct sockaddr_in
//bind connect accept函数传参的时候用(早期)进行类型转换 (sockaddr*)&addr
//struct sockaddr_in中:sin_family 表示选用的协议(IPV4/IPV6)
// sin_port 端口号(涉及到字节序转换)
// sin_addr ip地址,这个是个结构体,但是只有一个成员,所以赋值的时候:addr.sin_addr.s_addr=...
//网络套接字函数:socket函数,
//#include<sys/types.h>#include<sys/socket.h>
//创建套接字
//int socket(int domain, int sype, int protocol)
// AF_UNIX 通信协议(流式(TCP)/报式(UDP)) 0(采用这种协议的默认协议)
//往套接字上绑ip和端口号 int bind(int sockfd,const struct sockaddr *sddr,scoklen_t addrlen) 成功返回0,失败返回-1
// 文件描述符 ip 结构体的长度
//listen(int sockfd,int backlog)监听,用来指定监听上线数,服务器启动之后等待客户发起连接,连接建立好了(经过三次握手)开始传递数据,listen()指定同时允许多少个客户与我建立连接
//accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen):接收一个连接请求 服务器调用,如果调用成功,返回一个新的文件描述符,针对于接受连接的套接字,不是自己创建的那个
//socket()的返回值 传出参数,返回的是与我建立连接的客户端的地址信息 传入传出参数,描述结构体大小
//connect(int sockfd,struct sockaddr *addr,socklen_t addrlen)
//TCP服务器端:socket() 创建套接字 bind()绑定ip地址和端口号 listen() accept() 等待用户发起连接,如果用户没有发起连接,阻塞直到有客户端连接 read() 处理请求 write() close()
//server.c
#include<stdio.h>
#include<unustd.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<ctype.h>//toupper
#include<arpa/inet.h>
#define SER_PORT 6666
#define SERV_IP "127.0.0.1"
int main()
{
int lfd,cfd;//cfd是与客户端建立连接的文件描述符
struct sockaddr_in serv_addr,client_addr;
socklen_t client_addrlen;
char buf[BUFSIZ];
int n;
lfd=socket(AF_INET,sock_STREAM,0);//三个参数,返回一个新的文件描述符
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SER_PORT);//对应一个端口1000一下的给系统,最大不要超过65535,将来要通关bind函数绑定套接字,所以要进行字节序转换
serv_addr.sin_addr.s_addr = htol(INADDR_ANY);//对应一个ip地址,用htol()必须是数字,“127.0.0.1”是字符串,所以要用
//INADDR_ANY 可以绑定本地可用的任意IP 直接是数值类型
bind(lfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr)););//强转
listen(lfd, 128);//默认值(上线)128
client_addrlen = sizeof(client_addr);
cfd=accept(lfd,&client_addr,&client_addrlen);//在socket 上接受一个文件描述符,也会返回一个文件描述符
//accept的第二个参数是客户端的addr ,第三个参数是传入传出的,因为有传入,所以要先把类型定义出来
n=read(cfd, buf, sizeof(buf));//从cfd中读到buf里面去,n记录一共读了几个字节
//小写转大写
for (int i;i < n; ++i)
{
buf[i] = toupper(buf[i]);
}
write(cfd, buf, n);
close(lfd);
close(cfd);
return 0;
}
Linux系统下的网络编程之服务器端server.c
最新推荐文章于 2022-09-19 11:38:34 发布