socket tcp
程序员文章站
2022-06-16 23:42:34
...
socket 代码编成
client–客户端代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
int main(int argc,char *argv[])
{
int sock_fd; // 套接字描述符
struct sockaddr_in s_addr; // 套接字地址
int buflen = 1000; // 默认传入长度1000
char sbuf[1000]={0}; // 设置发送buf变量
int port = 8888; // 默认端口号8888
int i=1; // 传入参数位置变量
char id_addr[20] = "0.0.0.0"; // 连接端口默认为本地连接
if((sock_fd = socket(AF_INET, SOCK_STREAM, 0))<0) //初始化一个套接字 获得套接字描述符
{
perror("socket");
return -1;
}
while(argv[i]!=NULL) // 检测参数设置
{
if(argv[i][0]!='-') // 输入不规范 退出
{
printf("请输入正确格式\n");
return -1;
}
switch (argv[i][1])
{
case 'i': //设置ip地址
if(strlen(argv[i+1])>15) // 输入ip地址不规范 退出
{
printf("请输入合法地址 \n");
return -1;
}
strcpy(id_addr,argv[i+1]);
break;
case 'p': //设置端口号
port = atoi(argv[i+1]);
break;
case 'l': //设置传入长度
buflen = atoi(argv[i+1]);
break;
default:
break;
}
i+=2;
}
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(port);
s_addr.sin_addr.s_addr = inet_addr(id_addr); // 设置套接字内容
if(connect(sock_fd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr)) == -1) //开始连接服务器
{
perror("connect");
return -1;
}
printf("connect success \n"); //打印连接信息
while(1)
{
char rbuf[100]={0}; //接受缓存区
printf("请输入你要的发送的:");
fgets(sbuf,100,stdin); // 从标准输入获得数据到sbuf
write(sock_fd,sbuf,buflen); // 发送信息
read(sock_fd,rbuf,buflen); // 从套接字中读书据
printf("主机发送:%s\n",rbuf);
if(!strncasecmp(sbuf,"quit",4)) // 判断输入是否为退出信号
{
break;
}
}
return 0;
}
server --服务器代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
int main(int argc,char *argv[])
{
time_t time_raw_format; //时间变量
int sock_fd, sock_sd; //监听套接字描述符 接受发送套接字描述符
int maxfd; // select最大值
struct sockaddr_in r_addr,s_addr; //监听套接字地址 发送接受套接字地址
fd_set rfds, tmpfds; //select 的fd集合 和临时fd集合
int buflen = 1000; //设置默认传输长度
char buf[1000]={0}; //传输buf
int port = 8888; //默认设置端口8888
int i=1; //判断传入参数所需变量
if((sock_fd = socket(AF_INET, SOCK_STREAM, 0))<0) //创建套接字
{
perror("socket");
return -1;
}
while(argv[i]!=NULL)
{
if(argv[i][0]!='-')
{
printf("请输入正确格式\n");
return -1;
}
switch (argv[i][1])
{
case 'p': //设置监听端口号
port = atoi(argv[i+1]);
break;
case 'l': //设置传输数据长度
buflen = atoi(argv[i+1]);
break;
default:
break;
}
i+=2;
}
r_addr.sin_family = AF_INET;
r_addr.sin_port = htons(port);
r_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
if(bind(sock_fd,(struct sockaddr *)&r_addr,sizeof(r_addr))!=0) //绑定连接
{
perror("bind");
return -1;
}
printf("bind success \n"); // 打印成功信息
if(listen(sock_fd,20)!=0) // 监听
{
perror("listen");
return -1;
}
printf("listen success \n"); // 打印成功信息
FD_ZERO(&rfds); // 清空FD结构体
FD_SET(sock_fd,&rfds); // 加入监听套接字到轮训
FD_SET(0,&rfds); // 加入输入到轮训
maxfd = sock_fd; // 设置最大轮训
while(1)
{
tmpfds = rfds; //由于select会清空未发生变化的所以需要使用临时变量添加
int ret = select(maxfd+1, &tmpfds, NULL, NULL, NULL); //开始轮训 阻塞
if(ret < 0)
{
perror("select");
return -1;
}
for(int i = 0; i < maxfd+1; i++)
{
if(FD_ISSET(i,&tmpfds))
{
if(i == sock_fd)
{
socklen_t len = sizeof(s_addr);
if((sock_sd = accept(sock_fd,(struct sockaddr *)&s_addr,&len))<0) //接受描述符
{
perror("accept");
return -1;
}
printf("accept success \n"); // 打印成功
maxfd = maxfd > sock_sd ? maxfd : sock_sd ; //找出最大值
FD_SET(sock_sd,&rfds); //添加到FD结构体中
}
else if(i!=0)
{
char sbuf[100]={0};
bzero(buf,buflen);
read(i,buf,buflen);
printf("%d 发送的是:%s",i,buf);
printf("端口号是 : %d",ntohs(s_addr.sin_port));
time ( &time_raw_format ); //获取当前时间
sprintf(sbuf,"%s:%s",ctime(&time_raw_format),buf); //将当前是时间和受到内容给sbuf
write(i,sbuf,buflen); //发送sbuf
}
else
{
char tbuf[100]={0};
printf("请输入你要的发送的:");
fgets(tbuf,100,stdin); // 从标准输入获得数据到buf
if(!strncasecmp(tbuf,"quit",4)) // 判断输入是否为退出信号
{
close(sock_fd);
return 0;
}
}
}
}
if(!strncasecmp(buf,"quit",4))
{
break;
}
}
return 0;
}
end