實現的功能是可以socket服務器允許多個客戶端連接,連接到服務器的時候能夠打印出連接的IP地址和端口,服務端連接到數據能夠將客戶端的IP地址和發送內容打印出來。
效果:
服務端
appledeMacBook-Pro:聊天室 apple$ ./a.out 8888
有一個遠程機器連接到本機,ip地址:127.0.0.1,端口:40927
分配句柄成功
從客戶端:127.0.0.1獲取到數據vvv
從客戶端:127.0.0.1獲取到數據0f
從客戶端:127.0.0.1獲取到數據.test data
客戶端
appledeMacBook-Pro:c++Primer apple$ telnet 127.0.0.1 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
恭喜你成功連接到本服務器
vvv
vvv
0f
.0f
test data
.test data
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <pthread.h>
struct ClientInfo{
int newsockfd;
char* Ip;
}clientInfo;
void* connection_handler(void *);
void error(const char *msg)
{
perror(msg);
exit(1);
}
//因為是直接通過telent測試在發送的時候會帶一個\n不能直接通過strcmp來比,所以寫了下面的程序來處理
int isExit(char *s1)
{
if(strlen(s1)<6)
{
return 0;
}
char const *str="quit";
while(*str!='\0')
{
if(*str-*s1==0)
{
}
else {
printf("不同的是:%c,%c\n",*str,*s1);
return 0;
}
str++,s1++;
}
return 1;
}
int main(int argc, char const* argv[])
{
pthread_t thread_id;
int sockfd,newsockfd,portno;
socklen_t client;
struct sockaddr_in serv_addr,cli_addr;
int n;
if(argc<2){
fprintf(stderr,"請啟動程序的時候輸入一個正確的端口號");
exit(1);
}
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
error("打開Socket錯誤");
}
bzero((char *)&serv_addr,sizeof(serv_addr));
portno=atoi(argv[1]);
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=INADDR_ANY;
serv_addr.sin_port=htons(portno);
if(bind(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0)
{
error("綁定端口錯誤");
}
listen(sockfd,5);
client=sizeof(cli_addr);
while((newsockfd=accept(sockfd,(struct sockaddr *)&cli_addr,&client)))
{
printf("有一個遠程機器連接到本機,ip地址:%s,端口:%d\n",inet_ntoa(cli_addr.sin_addr),cli_addr.sin_port);
clientInfo.newsockfd=newsockfd;
clientInfo.Ip=inet_ntoa(cli_addr.sin_addr);
if( pthread_create( &thread_id , NULL , connection_handler , (void*) &clientInfo) < 0)
{
perror("創建線程失敗");
return 1;
}
puts("分配句柄成功");
}
if(newsockfd<0)
{
error("接受客戶端請求失敗");
}
close(newsockfd);
close(sockfd);
return 0;
}
void *connection_handler(void* arg)
{
ClientInfo *Client;
Client=(struct ClientInfo*) arg;
int sock=Client->newsockfd;
char* c=Client->Ip;
int read_size;
char buffer[256];
char *message , client_message[2000];
//改善一個歡迎信息到客戶端
message = "恭喜你成功連接到本服務器\n";
write(sock , message , strlen(message));
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
client_message[read_size]='\0';
printf("從客戶端:%s獲取到數據%s",c,client_message);
write(sock,client_message,strlen(client_message));
memset(client_message,0,2000);
}
if(read_size==0)
{
puts("客戶端關閉");
}
else if(read_size==-1)
{
perror("接收數據錯誤");
}
}