Linux下的网络编程(一)TCP编程

服务器与客户端的概念:

服务器: 在一次通讯中,提供数据的为服务器

客户端: 在一次通讯中,获取数据的为客户端


协议的选择(两种不同的协议有两种不同的编程方式):
TCP: 面向连接的(不断发送数据)    可靠的(数据完整,例如银行交易往来数据)            流式服务

UDP: 无连接(间断发送数据)           不可靠的(可能会有数据丢失,例如视频数据)        数据报服务


关于TCP 的编程流程:

server:      socket(打开网络接口)    bind(将服务器的IP地址与端口号与socket绑定)        listen(监听连接)       accept(拿出一个连接)      recv/send(收发数据)       close(关闭连接)

client:       socket        /*bind*/(可要可不要)      connect(发起连接)      recv/send      close


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

domain::  协议簇 AF_INET

type::  选择协议 SOCK_STREAM(tcp)  SOCK_DGRAM(udp)

protocol::  0


int bind(int sockfd, struct sockaddr *addr, int addrlen);

addr:: 指定 IP 地址和端口号

addrlen::地址长度


struct sockaddr_in

{

sa_family_t sin_family;          // 地址簇 AF_INET

u_int16_t sin_port ;              // 端口号 网络字节序(大端模式) PC 机(小端模式)

struct in_addr sin_addr;       // IP 地址

}

struct in_addr

{

u_int32_t s_addr;        // IP 地址最终的表示

}


int listen(int sockfd, int size);


int accept(int sockfd, struct sockaddr *addr, int *addrlen);      //可能会阻塞

返回值: 失败返回-1,成功返回获取到的和客户端连接的文件描述符
addr:: 记录客户端的 IP 地址和端口号


int connect(int sockfd, struct sockaddr* addr, int addrlen);

addr:: 要连接的服务器的 IP 地址和端口号


命令:netstat -atp               显示本机上所有的 TCP 服务程序以及其占用的端口号


具体实现代码:

服务器:

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


void  main()
{
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	assert(sockfd!=-1);

	struct sockaddr_in ser,cli;
	ser.sin_family=AF_INET;//地址簇
	ser.sin_port=htons(6000);//端口号,5000以内的不用   htons 主机转网络short模式
	ser.sin_addr.s_addr=inet_addr("127.0.0.1");    //inet_addr完成类型转化 字符串类型转换成无符号整形  点分十进制

	int res=bind(sockfd,(struct sockaddr*)&ser,sizeof(ser));  //第二个参数获取客户端地址
	assert(res!=-1);//崩溃要么地址不对,要么端口号正在被使用或无权限
	
	listen(sockfd,5);//监听哪个套接字 5创建队列大小

	int len=sizeof(cli);
	int c=accept(sockfd,(struct sockaddr*)&cli,&len);//第二个参数保存获取的端口号和IP地址  失败返回-1,成功拿出一个连接
	assert(c!=-1);

	char buff[128]={0};
	recv(c,buff,127,0); //获取的对象、数据、多少字节、属性
	printf("recv::%s\n",buff);
	send(c,"i know",strlen("i know"),0);

	close(c);
	close(sockfd);
}

客户端:

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

void main()
{
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	assert(sockfd!=-1);

	struct sockaddr_in ser,cli;
	ser.sin_family=AF_INET;
	ser.sin_port=htons(6000);//服务器的端口号
	ser.sin_addr.s_addr=inet_addr("127.0.0.1");

	int res=connect(sockfd,(struct sockaddr*)&ser,sizeof(ser));//
	assert(res!=-1);

	send(sockfd,"hello world",strlen("hello world"),0);
	char buff[128]={0};
	recv(sockfd,buff,127,0);
	printf("recv::%s\n",buff);
	close(sockfd);
}


运行时先运行服务器后运行客户端,运行结果如下:











  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值