linux网络编程之基础模型

客户端,服务器通信模型

在这里插入图片描述

创建套接字

int socket(int domain,int type,int protocol);

domain:协议族
AF_UINX(本地套接字),
AF_INET(网络套接字)
type:套接字通信类型
SOCK_STREAM:有序,可靠,面向连接的双向字节流
SOCK_STRDGRAM数据报服务,UDP
protocol:使用的协议

命名套接字

bind系统调用把参数address中的地址分配给与文件描述符socket关联的未命名套接字

int bind(int socket,const struct sockaddr *address,size_t address_len);

创建套接字队列

为了在套接字上接受进入的连接,服务器需要创建一个队列来保持未处理的请求

int listen(int socket,int backlog);

接受连接

一旦服务器程序创建并命名了套接字后,它就可以通过accept系统调用来等待客户建立套接字连接。

int accept(int socket,struct sockaddr*address,size_t *address_len);

如果套接字队列中有没有处理的连接,accept将阻塞直到有客户建立连接为止。可以通过对套接字设置O_NONBLOCK标志来改变这一行为

int flags = fcntl(socket,F_GETFL,0);

fcntl(socket,F_SETFL,O_NONBLOCK | flags);

请求连接

客户程序通过在一个未命名套接字服务器监听套接字之间建立连接的方法来连接到服务器

int connect(int socket.const struct sockaddr *addrsss,size_t address_len);

参数socket指定的套接字将连接到参数address指定的服务器套接字。

服务端程序

1)打印客户端的ip与port
2)将接收到的数据进行大写转换并回显

#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<sys/un.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<assert.h>
#include<string.h>
#include<ctype.h>
#include<errno.h>

#define SERVER_PORT 6666 

static void sys_error(const char *str)
{
	perror(str);
	exit(1);
}

int main(int argc,char *argv[])
{
	int lfd = 0,cfd = 0;
	int ret;
	char buffer[BUFSIZ,client_ip[56];

	struct sockaddr_in serv_addr,clit_addr;
	socklen_t clit_addr_len,client_ip_len;
	
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(SERVER_PORT);
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	lfd = socket(AF_INET,SOCK_STREAM,0);
	if(lfd == -1)
		sys_error("socket error");

	bind(lfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));

	listen(lfd,128);
    socklen_t client_addrlength = sizeof(clit_addr);
    cfd = accept(lfd,(struct sockaddr *)&clit_addr,&client_addrlength);
    if(cfd < 0)
                printf("error is:%d\n",errno);
    printf("client ip:%s,port=%d\n", inet_ntop(AF_INET,&clit_addr.sin_addr.s_addr,client_ip,sizeof(client_ip)),
                        ntohs(clit_addr.sin_port));

	while(1){
		ret = read(cfd,buffer,sizeof(buffer));

        	write(STDOUT_FILENO,buffer,ret);
        	for(int i = 0;i<ret;i++)
        	{
                	buffer[i]=toupper(buffer[i]);
        	}
        	write(cfd,buffer,ret);
	}
        close(cfd);
	    close(lfd);
        return 0;
}

服务端

(base) wy@ubuntu:~/network$ ./serv2 
client ip:127.0.0.1,port=54192
hello

客户端

(base) root@ubuntu:/home/wy/network# nc 127.0.0.1 6666
hello
HELLO

客户端程序

#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<sys/un.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<assert.h>
#include<string.h>
#include<ctype.h>
#include<errno.h>

#define SERVER_PORT 6666 


static void sys_error(const char *str)
{
	perror(str);
	exit(1);
}

int main(int argc,char *argv[])
{
	int cfd = 0;
	int ret;
	char buffer[BUFSIZ];

	struct sockaddr_in serv_addr;
	socklen_t clit_addr_len,client_ip_len;
	
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(SERVER_PORT);

	inet_pton(AF_INET,"127.0.0.1",&serv_addr.sin_addr);

	cfd = socket(AF_INET,SOCK_STREAM,0);
	if(cfd == -1)
		sys_error("socket error");

	ret = connect(cfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
	if(ret != 0)
		sys_error("connect error\n");

	while(1){
        	write(cfd,"hello\n",6);
        	ret = read(cfd,buffer,sizeof(buffer));
		printf("buffer=%s\n",buffer);
		sleep(1);
	}
        close(cfd);
        return 0;
}

注:inet_pton(AF_INET,“127.0.0.1”,&serv_addr.sin_addr);

服务端

(base) root@ubuntu:/home/wy/network# ./serv2 
client ip:127.0.0.1,port=54204
hello
hello

客户端

(base) wy@ubuntu:~/network$ ./client2
buffer=HELLO

buffer=HELLO

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为了维护世界和平_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值