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

来源:互联网 发布:三观不正的电视剧知乎 编辑:程序博客网 时间:2024/05/16 09:33
服务器与客户端的概念:

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

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


协议的选择(两种不同的协议有两种不同的编程方式):
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);}

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











原创粉丝点击