一、socket网络编程结构
tcp socket网络编程的结构:
客户端:socket-------------------------connect--------(send/recv)--------close
服务器:socket----bind----listen------accept---------(recv/send)--------close
服务器先运行,在accept环节阻塞等待客户端的连接信息,再运行客户端,进行到connect环节时向服务器端发送连接信息,双方正式建立起socket的联系。之后双方可以进行信息的交互(send/recv),在结束信息交互工作后,close关闭套接字。
二、基本函数
1、socket:创建一个socket对象
?2、bind:把ip地址和端口号绑定在socket上
3、?listen:设置服务器可以接收客户端的连接请求
4、accept:?服务器用于获得连接请求,并监听连接。
?5、connect:客户端用于和服务器建立连接
?6、send:建立连接后,发送数据
?7、recv:建立连接后,接收数据
三、客户端和服务端代码
客户端代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
//编写一子函数,请求连接tcp服务器端
//参数1:IP地址 char * "192.168.8.61"
//参数2:port端口 int port
//返回值:创建好的socket对象
int tcp_connect(const char * ip,int port)
{
//1.创建TCP套接字(socket) socket()
int tcp_socket = socket(AF_INET,SOCK_STREAM,0);
if(tcp_socket<0)
{
perror("socket error");
return -1;
}
printf("套接字创建成功!\n");
//2.设置对方IP地址和端口号 struct sockaddr_in
struct sockaddr_in server;
server.sin_family=AF_INET;//协议
server.sin_port=htons(port);//端口号
server.sin_addr.s_addr=inet_addr(ip);//网络ip地址
//3.请求连接 connect()
if(connect(tcp_socket,(struct sockaddr *)&server,sizeof(server))<0)
{
perror("connect error");
return -1;
}
printf("连接套接字成功!\n");
return tcp_socket;
}
//编写一子函数,进行tcp通信
//参数1:创建好的socket对象
//返回值:void
void tcp_com(int tcp_socket)
{
//通信 读/写 read()/write()
char buf[50] = {'\0'};
printf("发送:");
fgets(buf,sizeof(buf),stdin);
//write(tcp_socket,buf,sizeof(buf));
send(tcp_socket,buf,sizeof(buf),0);
memset(buf,'\0',sizeof(buf));
printf("接收:");
//read(tcp_socket,buf,sizeof(buf));
recv(tcp_socket,buf,sizeof(buf),0);
printf("%s",buf);
}
int main(int argc, const char *argv[])
{
if(argc != 3)
{
printf("输入错误!请输入./文件 网络地址 端口号\n");
return -1;
}
//1.连接Tcp服务器
int tcp_socket = tcp_connect(argv[1],atoi(argv[2]));
//2.tcp通信
tcp_com(tcp_socket);
//3.关闭socket close()
close(tcp_socket);
return 0;
}
服务端代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
//编写一子函数,监听是否有人连接
//参数1:ip地址 char *ip
//参数2:端口号 int port
//返回值:返回监听的socket对象
int tcp_server(const char * ip,int port);
int tcp_server(const char * ip,int port)
{
//1.创建tcp_socket对象
int tcp_socket = 0;
tcp_socket = socket(AF_INET,SOCK_STREAM,0);
if(tcp_socket<0)
{
perror("socket error");
return -1;
}
printf("套接字创建成功!\n");
//2.绑定自己的ip地址和端口号
struct sockaddr_in myaddr;
myaddr.sin_family=AF_INET;//协议
myaddr.sin_port=htons(port);//端口号
myaddr.sin_addr.s_addr=inet_addr(ip);//网络ip地址
//INADDR_ANY 自动获取一个ip地址,直接使用
if(bind(tcp_socket,(struct sockaddr *)&myaddr,sizeof(myaddr))<0)
{
perror("bind error");
return -1;
}
printf("bind ok\n");
//3.监听是否有人连接
if(listen(tcp_socket,5)<0)
{
perror("listen error");
return -1;
}
printf("listen ok\n");
return tcp_socket;
}
//编写一子函数,进行tcp通信
//参数1:新生成的socket对象
//返回值:void
void tcp_com(int newfd);
void tcp_com(int newfd)
{
//读/写 read()/write()
char buf[50] = {'\0'};
printf("接收:");
//read(newfd,buf,sizeof(buf));
recv(newfd,buf,sizeof(buf),0);
printf("%s",buf);
memset(buf,'\0',sizeof(buf));
printf("发送:");
fgets(buf,sizeof(buf),stdin);
//write(newfd,buf,sizeof(buf));
send(newfd,buf,sizeof(buf),0);
}
int main(int argc, const char *argv[])
{
if(argc != 3)
{
printf("输入错误!请输入./文件 网络地址 端口号\n");
return -1;
}
//1.获取监听成功的socket对象
int tcp_socket = tcp_server(argv[1],atoi(argv[2]));
//2.接受连接生成新的socket对象
int newfd=0;
//不关心对方的ip地址和端口,参数2,3设为NULL
//newfd=accept(tcp_socket,NULL,NULL);
//关心对方ip地址和端口号
struct sockaddr_in client;
memset(&client,'\0',sizeof(client));
int len=sizeof(client);
newfd=accept(tcp_socket,(struct sockaddr *)&client,&len);
if(newfd<0)
{
perror("accept error");
return -1;
}
printf("client ip = %s\tport = %d\t accept ok\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
//3.tcp通信
tcp_com(newfd);
//4.关闭socket close()
close(newfd);
close(tcp_socket);
return 0;
}
|