1.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/select.h>
int main(int argc, const char *argv[])
{
//创建套接字
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
perror("socket create error");
return -1;
}
printf("sockfd create success\n");
int opt=1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
//绑定套接字
struct sockaddr_in saddr,caddr;
saddr.sin_family=AF_INET;
saddr.sin_port=htons(atoi(argv[1]));
saddr.sin_addr.s_addr=inet_addr(argv[2]);
int len=sizeof(caddr);
if(bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr))<0)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//创建监听队列
if(listen(sockfd,5)<0)
{
perror("liseten is error");
return -1;
}
//创建一个存储文件描述符的表
fd_set readfds,tempfds;
//对表初始化清空
FD_ZERO(&readfds);
//将需要的文件描述符添加到表内
FD_SET(sockfd,&readfds);
FD_SET(0,&readfds);
int maxfd=sockfd;
char send_buf[128];
char recv_buf[128];
while(1)
{
bzero(send_buf,sizeof(send_buf));
bzero(recv_buf,sizeof(recv_buf));
//将原表内的内容拷贝到备份表
tempfds=readfds;
//利用select 进行轮训监测
if( select(maxfd+1,&tempfds,NULL,NULL,NULL) < 0 )
{
perror("select is err:");
return -1;
}
//判断文件描述符是否产生响应
if(FD_ISSET(0,&tempfds))
{
printf("please enter:");
fgets(send_buf,sizeof(send_buf),stdin);
if( send_buf[strlen(send_buf)-1] == '\n' )
send_buf[strlen(send_buf)-1] = '\0';
for(int i=4;i<=maxfd;i++)
{
if(FD_ISSET(i,&readfds))
{
send(i,send_buf,sizeof(send_buf),0);//发送信息
}
}
printf("发送成功\n");
}
//判断文件描述符是否产生响应
if(FD_ISSET(sockfd,&tempfds))
{
int acceptfd=accept(sockfd ,(struct sockaddr*)&caddr,&len);
if(acceptfd<0)
{
perror("accept error");
return -1;
}
FD_SET(acceptfd,&readfds);
if(acceptfd>maxfd)
{
maxfd=acceptfd;
}
printf("new client connected: %d\n", acceptfd);
for(int i=4;i<=maxfd;i++)
{
if(FD_ISSET(i,&tempfds))
{
int ret=recv(i,recv_buf,sizeof(recv_buf),0);
if(ret<0)
{
perror("recv error");
return -1;
}
else if(ret==0)
{
close(i);//关闭i文件描述符
FD_CLR(i,&readfds);
if(i == maxfd)
{
maxfd--;
}
printf("client exit\n");
}
else
{
printf("client:%d %s\n",i,recv_buf);
}
}
}
}
}
close(sockfd);
return 0;
}
2.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
int main(int argc, const char *argv[])
{
if (argc != 3) {
fprintf(stderr, "Usage: %s <port> <ip>\n", argv[0]);
return -1;
}
// 创建套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket create error");
return -1;
}
printf("socket create success\n");
struct sockaddr_in caddr;
caddr.sin_family = AF_INET;
caddr.sin_port = htons(atoi(argv[1]));
caddr.sin_addr.s_addr = inet_addr(argv[2]);
// 链接服务器
if (connect(sockfd, (struct sockaddr*)&caddr, sizeof(caddr)) < 0) {
perror("connect error");
close(sockfd);
return -1;
}
// 定义发送信息的容器
char send_buf[128] = {0};
char recv_buf[128] = {0};
fd_set readfds, tempfds;
int maxfd = sockfd;
while (1) {
// 每次循环开始时重新初始化 readfds
FD_ZERO(&readfds);
FD_SET(0, &readfds);
FD_SET(sockfd, &readfds);
tempfds = readfds;
if (select(maxfd + 1, &tempfds, NULL, NULL, NULL) < 0) {
perror("select error");
close(sockfd);
return -1;
}
// 处理标准输入
if (FD_ISSET(0, &tempfds)) {
bzero(send_buf, sizeof(send_buf));
printf("请输入: ");
if (fgets(send_buf, sizeof(send_buf), stdin) != NULL) {
size_t len = strlen(send_buf);
if (len > 0 && send_buf[len - 1] == '\n') {
send_buf[len - 1] = '\0'; // 去掉换行符
}
// 发送
if (send(sockfd, send_buf, strlen(send_buf), 0) < 0) {
perror("send error");
close(sockfd);
return -1;
}
}
}
// 处理从服务器接收的数据
if (FD_ISSET(sockfd, &tempfds)) {
bzero(recv_buf, sizeof(recv_buf));
int ret = recv(sockfd, recv_buf, sizeof(recv_buf) - 1, 0); // 留出空间给'\0'
if (ret < 0) {
perror("recv error");
close(sockfd);
return -1;
} else if (ret == 0) {
printf("Server disconnected\n");
close(sockfd);
return 0;
} else {
recv_buf[ret] = '\0'; // 确保接收到的数据是以'\0'结尾
printf("recv: %s\n", recv_buf);
}
}
}
close(sockfd);
return 0;
}