Linux系统下的网络编程之服务器端server.c

//套接字成对出现,要绑定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;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值