回声服务器

网络编程 回声服务器

服务器端

#include<sys/types.h>
#include<sys/socket.h>
#include<iostream>
#include<netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include<unistd.h>
using namespace std;

#define duankou 999

int main2() {
int box;
box = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in label;
bzero(&label, sizeof(label));
label.sin_family = AF_INET;
label.sin_addr.s_addr = htonl(INADDR_ANY);
label.sin_port = htons(duankou);
//函数说明htons()用来将参数指定的16位
//hostshort转换成网络字符顺序。返回值
//返回对应的网络字符顺序
bind(box, (struct sockaddr*)&label, sizeof(label));//
listen(box, 65);

cout << "wait .........." << endl;
while (1) {
struct sockaddr_in kehu;//客服端的结构体
int b;
socklen_t a; // 实际上是int 历史原因造成
a=sizeof(kehu);
b=accept(box, (struct sockaddr*)&kehu, &a);
// 这里也给客户端的机构体赋值

char addr[64];
cout << "客户端 ip" <<
inet_ntop(AF_INET, &kehu.sin_addr.s_addr, addr, sizeof(addr))<<endl;
//将网络字节序转换成 主机字节序的字符串
cout << "客户端的端口号" << ntohs(kehu.sin_port) << endl;
//函数说明
//ntohs()用来将参数指定的16位netshort转换成主机字符顺序。
//返回值返回对应的主机顺序。
char buff[250]; int lenth;
lenth=read(b, buff, (sizeof(buff)) - 1); // 读取客户端发送的数据 
buff[lenth] = '\0';
cout << buff << endl;
int lenth_2;
lenth_2=write(b, buff, lenth);// 写入客户端 
close(b);
}

}

socket  

socket  返回值是一个整数  文件句柄 可以通过这个文件句柄读写

 

网络字节序

主机字节序: 一般都是小端字节序

网络字节序  一般都是大端格式 

#include<arpa/inet.h> 

unit32_t  htonl(unit32_t  hostlong)  把主机转换成网络   32位   ip       整数

unit16_t  htons(unit16_t  hostlong) 把主机转换成网络   16位  端口    整数

unit32_t  ntohl(unit32_t  netlong)  把网络转换成主机     32位  ip        整数 

unit16_t  ntohs(unit16_t  netshort) 把网络转换成主机    16位  端口   整数

   

sockaddr_in  结构体 后面出现 针对于 ipv4  使用时 转化成 sockaddr *

sin_family 选择协议家族    AF_INET   (ipv4)

sin_addr.s_addr   保存ip地址 

sin_port   保存端口号 

ip地址转化函数

inet_pton( ) 把ip字符串转化成大端格式的网络字节序的ip

inet_ntop( ) 把网络字节序转化成ip的字符串

inet_ntop(AF_INET,&sin_addr.s_addr,保存的字符串,字符串的大小 );

 

int main(void) {
const char a[]= "1.2.3.4";// 小端格式 主机字节序
struct sockaddr_in xx;
inet_pton(AF_INET, a,&xx.sin_addr.s_addr);//转换成大端格式
//这里保存的是整数 xx.sin_addr.s_addr;

printf("%x\n",xx.sin_addr.s_addr);
// 保存的是大端格式 网络字节序 
printf("%d\n",ntohl(xx.sin_addr.s_addr));
// 小端格式 主机字节序 

 

socket  函数

socket  的头文件 #include<sys/types.h>  #include<sys/socket.h>

int socket(int domain,int type,int protocol);  也就是向系统注册,通知系统建立一通信端口

返回值
成功则返回socket处理代码,失败返回-1。

domain(域名)

参数domain 指定使用何种的地址类型,  AF_INET   Ipv4网络协议

                                                                AF_INET6   ipv6 网络协议

                                                                AF_UNIX     本地协议

type

SOCK_STREAM 提供双向连续且可信赖的数据流,即TCP协议 

protocol

用来指定socket所使用的传输协议编号,通常此参考不用管它,设为0即可。

bind 函数

int  bind(int sockfd,const struct sockaddr*addr, socklen_t   addrlen)

将socket文件句柄和 ip地址和端口号进行绑定

int sockfd  socket  文件句柄

sockaddr*addr   ip地址和端口号的结构体的地址

socklen_t   addrlen   结构体的长度 

listen  函数

int listen(int s,int backlog);

listen()用来等待参数s 的socket连线。

参数backlog指定同时能处理的最大连接要求

返回值
成功则返回0,失败返回-1,错误原因存于errno

 accept函数

int accept(int s,struct sockaddr * addr,int * addrlen);

s的socket连线 参数s的socket必需先经bind()、listen()函数处理过

参数addr所指的结构会被系统填入远程主机的地址数据

参数addrlen为scokaddr的结构长度

 

返回值
成功则返回新的socket处理代码,失败返回-1,错误原因存于errno中。

 

connect 函数

定义函数
int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);
函数说明
sockfd   客服端的文件句柄 

serv_addr  客服器的ip和端口号的结构体

addrlen    结构体的长度 

成功则返回0,失败返回-1,错误原因存于errno中。

上一篇:数学笔记20——三角替换1(sin和cos)


下一篇:三维地图实现下雨效果源代码