socket阻塞型服务端实现
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
//服务器端
void *fun_thrReceiveHandler(void *socketInfo);
void *fun_thrAcceptHandler(void *socketListen);
void *fun_id(void*on);
typedef struct MySocketInfo{
int socketCon;
char *ipaddr;
uint16_t port;
}_MySocketInfo;
// 客户端数组
struct MySocketInfo arrConSocket[10];
int conClientCount = 0;
// 接受客户端线程列表
pthread_t arrThrReceiveClient[10];
int thrReceiveClientCount = 0;
int main()
{
int on=1;
printf("开始socket\n");
//创建套接字
int socketListen = socket(AF_INET, SOCK_STREAM, 0);
printf("socketListen= %d\n" ,socketListen);
if(socketListen < 0)
{
printf("创建失败\n");
exit(-1);
}
else
{
printf("创建套接字成功\n");
}
//通讯准备
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(2000);
int temp=1;
int socketset3= setsockopt(socketListen, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(temp));
if(socketset3<0)
{
perror("setsockopt");
exit(-1);
}
//本地地址与套接口捆绑
if(bind(socketListen, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) != 0)
{
perror("绑定ip地址、端口号失败\n");
exit(-1);
}
else
{
printf("绑定ip地址,端口号\n");
}
// 将套接字设为监听模式,等待队列最大长度为10
if(listen(socketListen, 10) != 0){
printf("开启监听失败\n");
exit(-1);
}
else
{
printf("开启监听成功\n");
}
pthread_t thrAccept;
pthread_create(&thrAccept,NULL,fun_thrAcceptHandler,&socketListen);
pthread_detach(thrAccept );//子线程与父线程分离开
pthread_t id = 0;
pthread_create(&id,NULL,fun_id,&on);
pthread_detach(id);
while(1)
{
printf("当前有接受数据线程多少个:%d\n",thrReceiveClientCount);
//向客户端发送数据
char userStr[30] = {'0'};
scanf("%s",userStr);
// 退出
if(strcmp(userStr,"q") == 0)
{
printf("用户选择退出!\n");
break;
}
if(conClientCount <= 0)
{
printf("没有客户端连接\n");
}
else
{
int i;
for(i=0; i<conClientCount; i++)
{
//把输入内容写入发送客户端的数组中
int sendMsg_len = send(arrConSocket[i].socketCon,userStr,300,0);
// printf("发送客户端的数据最大字节数:%d\n", sendMsg_len);
if(sendMsg_len > 0)
{
printf("向%s:%d发送成功\n",arrConSocket[i].ipaddr,arrConSocket[i].port);
}
else
{
printf("向%s:%d发送失败\n",arrConSocket[i].ipaddr,arrConSocket[i].port);
}
}
}
sleep(0.5);
}
return 0;
}
void *fun_id(void*on)
{
printf("error\n");
}
//与客户端连接
void *fun_thrAcceptHandler(void *socketListen)
{
while(1)
{
int sockaddr_in_size = sizeof(struct sockaddr_in);
struct sockaddr_in client_addr;
bzero(&client_addr,sizeof(struct sockaddr_in));
int _socketListen = *((int *)socketListen);
//创建一个与客户端连接的套接字
int socketCon = accept(_socketListen, (struct sockaddr *)(&client_addr), (socklen_t *)(&sockaddr_in_size));
printf("socketCon=%d\n",socketCon);
if(socketCon < 0)
{
printf("连接失败\n");
}
else
{
printf("连接成功 ip: %s:%d\r\n",inet_ntoa(client_addr.sin_addr),client_addr.sin_port);
}
printf("连接套接字为:%d\n",socketCon);
struct timeval stTimeout;
stTimeout.tv_sec = 10;
stTimeout.tv_usec = 0;
//套接口设置选项
int socketset1= setsockopt(socketCon, SOL_SOCKET, SO_SNDTIMEO, (char *)&stTimeout, sizeof(struct timeval));
int socketset2= setsockopt(socketCon, SOL_SOCKET, SO_RCVTIMEO, (char *)&stTimeout, sizeof(struct timeval));
if(socketset2<0)
{
printf("1111111\n");
}
else if(socketset2==0)
{
printf("222222\n");
}
else
{
printf("33333\n");
}
_MySocketInfo socketInfo;
socketInfo.socketCon = socketCon;
socketInfo.ipaddr = inet_ntoa(client_addr.sin_addr);
socketInfo.port = client_addr.sin_port;
arrConSocket[conClientCount] = socketInfo;
conClientCount++;
printf("连接了%d个用户\n",conClientCount);
pthread_t thrReceive = 0;
pthread_create(&thrReceive,NULL,fun_thrReceiveHandler,&socketInfo);
pthread_detach(thrReceive);
arrThrReceiveClient[thrReceiveClientCount] = thrReceive;
thrReceiveClientCount++;
sleep(0.5);
}
}
//接收客户端发来的数据
void *fun_thrReceiveHandler(void *socketInfo)
{
char buffer[30];
int buffer_length;
_MySocketInfo _socketInfo = *((_MySocketInfo *)socketInfo);
while(1)
{
bzero(&buffer,sizeof(buffer));
//读取出来的数据放在缓存区中
buffer_length = recv(_socketInfo.socketCon,buffer,300,0);
if(buffer_length == 0)
{
printf("%s:%d 客户端关闭\n",_socketInfo.ipaddr,_socketInfo.port);
conClientCount--;
break;
}
else if(buffer_length < 0)
{
printf("接受客户端数据失败\n");
}
buffer[buffer_length] = '\0';
printf("%s:%d 说:%s\n",_socketInfo.ipaddr,_socketInfo.port,buffer);
}
return NULL;
}
socket阻塞型客户端
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
//客户端阻塞
typedef struct MySocketInfo{
int socketCon;
unsigned long ipaddr;
unsigned short port;
}_MySocketInfo;
void *fun_thrReceiveHandler(void *socketCon);
int main()
{
printf("开始socket\n");
int socketCon = socket(AF_INET, SOCK_STREAM, 0);
if(socketCon < 0)
{
printf("创建TCP连接套接字失败\n");
exit(-1);
}
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
server_addr.sin_port=htons(2000);
struct timeval stTimeout;
stTimeout.tv_sec=5;
stTimeout.tv_usec=0;
int setsocktmp1=setsockopt(socketCon, SOL_SOCKET, SO_SNDTIMEO, (char *)&stTimeout, sizeof(struct timeval));
int setsocktmp2= setsockopt(socketCon, SOL_SOCKET, SO_RCVTIMEO, (char *)&stTimeout, sizeof(struct timeval));
if(setsocktmp2<0)
{
printf("1111111\n");
}
else if(setsocktmp2==0)
{
printf("222222\n");
printf("errno=%d",errno);
printf("error:%s\n",strerror(errno));
}
int res_con = connect(socketCon,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr));
if(errno!=EINPROGRESS)
{
printf("errno!=EINPROGRESS\n");
}
if(errno==EINPROGRESS)
{
printf("errno==EINPROGRESS\n");
}
if(res_con != 0){
printf("连接失败\n");
printf("res_con=%d\n",res_con);
// exit(-1);
}
else
{
printf("连接成功,连接结果为:%d\n",res_con);
}
pthread_t thrReceive;
pthread_create(&thrReceive,NULL,fun_thrReceiveHandler,&socketCon);
pthread_detach(thrReceive);
// printf("setsocktmp2= %d",setsocktmp2);
while(1)
{
char userStr[300] = {'0'};
scanf("%s",userStr);
if(strcmp(userStr,"q") == 0){
printf("退出!\n");
break;
}
// 发送消息
int sendMsg_len = send(socketCon,userStr,300,0);
if(sendMsg_len > 0){
printf("发送成功,服务端套接字:%d\n",socketCon);
}else{
printf("发送失败\n");
}
}
close(socketCon);
return 0;
}
void *fun_thrReceiveHandler(void *socketCon)
{
pthread_detach(pthread_self());//子线程自己分离自己线程
while(1)
{
char buffer[30];
int _socketCon = *((int *)socketCon);
int buffer_length = recv(_socketCon,buffer,300,0);
if(buffer_length == 0)
{
printf("服务器端异常关闭\n");
exit(-1);
}
else if(buffer_length < 0){
printf("接受服务器数据失败\n");
break;
}
buffer[buffer_length] = '\0';
printf("服务器说:%s\n",buffer);
}
return NULL;
}