TCP网络编程

编程模型函数化:
服务器:
创建socket:
函数:int socket(int domain,int type,int protocal)
功能:创建一个套接字
参数:domain:AF_INET   IPv4因特网域    AF_INET6  IPv6因特网域
    AF_UNIX UNIX域               AF_UNSPEC 未指定
    type:套接字类型
SOCK_DGRAM:长度固定的,无连接的不可靠报文传递
SOCK_RAM:IP协议的数据接口(POSIX1中可选)
SOCK_SEQPACKET:长度固定、有序、可靠的面向连接报文传递
SOCK_STREAM:有序、可靠、双向的面向连接字节流()
    protocal:通常是0
返回:套接字的fd
头文件:<sys/socket.h>
绑定地址:
函数:int bind(int sockfd,const struct sockaddr *addr,socklen_t len)
功能:选定一个网卡地址与套接字绑定
参数:sockfd:套接字的sockfd
    struct sockaddr{
            sa_family_t sa_family    协议族类型  AF_INET 代表ipv4
 
      char sa_data[14]            地址
}                              
通用地址类型
struct socketaddr_in{
short int sin_family;
unsigned short int sin_port;//端口
struct in_addr sin_addr;  //ip地址
unsigned char sin_zero[8];//填充
}
struct in_addr{
unsigned long s_addr     4字节
}
 
地址转换:in_addr_t inet_addr(const char *cp)
功能:将字符串形式的IP地址转化为整数型的IP地址(网络字节序)
范例:in_addr.saddr = inet_addr("192.168.1.1")
范例:char *inet_ntoa(struct in_addr)
功能:将整数型式的IP地址转化为字符型式的IP地址
返回:成功:0    失败:-1
头文件:<sys/types.h>  <sys/socket.h>
大端:
小端:
网络字节序:
uint32_t htonl(uint32_t hostlong);
将32位的数据从主机字节序转换为网络字节序
in_addr.saddr = htonl(INADDR_ANY)
uint16_t htons(uint16_t unit16_t hostshort);
将16位的数据从主机字节序转换为网络字节序
uint32_t ntonh(uint32_t netlong);
将32位的数据从网络字节序转换为主机字节序
uint16_t ntohs(uint16_t unit16_t netshort);
将16位的数据从网络字节序转换为主机字节序
监听端口:
函数:int listen(int sockfd,int backlog)
功能:1.服务器已经做好链接准备,等待客户机的链接
    2.用来设置服务器可以同时连接多少客户机
参数:sockfd:套接字fd    backlog:同时连接客户机的数量
返回:成功:0   失败:-1
头文件:<sys/socket.h>
等待连接
函数:int accept(int sockfd,struct sockadr *restrict addr,socklen_t *restrict len);
功能:等待客户机连接,没有客户机连接,停在这里等待
参数:sockfd:新的套接字fd
    addr:保存客户机的地址信息
    len:地址的长度
返回:成功:返回文件套接字描述符  失败:-1;
头文件:<sys/socket.h>
发|收数据:
函数:ssize_t send(int sockfd,const void *buf,size_t nbytes,int flags)
功能:发送数据 类型write
参数:sockfd:建立连接后的fd
   buf:要发送数据的位置
   nbytes:要发送数据的长度
   flags:标志
返回:成功:返回发送的字节数   失败:-1
头文件:<sys/socket.h>
函数:ssize_t recv(int sockfd,const void *buf,size_t nbytes,int flags)
功能:接收数据 类型write
参数:sockfd:建立连接后的fd
   buf:接收的数据保存的位置
   nbytes:接受到数据的长度
   flags:标志
返回:成功:返回接收的字节数   失败:-1
头文件:<sys/socket.h>
结束链接:close(sockfd)
客户机:
创建socket:
连接服务器:
函数:int connect(int sockfd,const struct sockaddr *addr,socklen_t len)
功能:链接服务器
参数:sockfd:套接字fd
   sockaddr:服务器地址
   len:地址长度
返回值:成功:0  失败:-1
头文件:<sys/socket.h>
收|发数据:
结束连接

 

 
//模型实例:一个客户机,一个服务器,利用TCP协议进行通信
//服务器代码
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/types.h>#define PORT 8888int main(){int sockfd,new_sockfd,nbyte;int ret;pid_t pid;size_t sin_len;char buffer[256];struct sockaddr_in server_addr,client_addr;//创建套接字sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd == -1){printf("套接字创建失败!\n");exit(1);}//绑定地址server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8888); //主机字节序转换为网络字节序 server_addr.sin_addr.s_addr = htonl(INADDR_ANY);if(bind(sockfd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr)) == -1){printf("地址绑定失败!\n");exit(1);}//监听端口if(listen(sockfd,128) == -1){printf("端口监听失败!\n");exit(1);}while(1){//等待连接if((new_sockfd=accept(sockfd,(struct sockaddr*)&client_addr,&sin_len)) == -1){printf("连接失败!\n");exit(1);} printf("server get connection from %s\n",inet_ntoa(client_addr.sin_addr));//创建子进程if((pid =fork()) ==0){//收发数据nbyte = recv(new_sockfd,buffer,128,0);buffer[nbyte] = '\0';printf("Receive char is:%s",buffer);//释放套接字close(new_sockfd);close(sockfd);exit(0);}else if(pid<0)printf("子进程创建错误\n");}close(sockfd);return 0;}
 
//客户机代码
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/types.h>#define PORT 8888int main(){int sockfd,new_sockfd;int ret;size_t sin_len;char buffer[256];struct sockaddr_in client_addr;client_addr.sin_family = AF_INET;client_addr.sin_port = htons(8888); //主机字节序转换为网络字节序 client_addr.sin_addr.s_addr = inet_addr("192.168.1.123");//创建套接字sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd == -1){printf("套接字创建失败!\n");exit(1);}if(connect(sockfd,(struct sockaddr*)&client_addr,sizeof(struct sockaddr)) == -1){printf("链接失败\n");exit(1);}//输入数据printf("请输入数据:\n");fgets(buffer,128,stdin);send(sockfd,buffer,strlen(buffer),0);//关闭链接close(sockfd);return 0;}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值