用到知识点:
1.套接字的创建、绑定、监听、接收、链接
2.多线程编程:线程创建、线程等待、线程分离、
3.字符串和IP地址的转化等
server.c
实现多个客户端连接服务器的功能
/*************************************************************************
> File Name: tserver.c
> Author: ZX
> Mail: 18829897183@163.com
> Created Time: Sun 12 Mar 2017 06:38:21 AM PDT
************************************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<pthread.h>
void* handle_fd(void* arg)
{
int sock = *((int*)arg);
char buf[1024];
while(1)
{
ssize_t s = read(sock, buf, sizeof(buf)-1);
if(s > 0)
{
buf[s-1] = 0;
printf("client# %s\n",buf);
}
else
{
printf("client is quit!\n");
break;
}
}
close(sock);
}
int statup(int port, const char* ip)
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
perror("socket");
return 1;
}
int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_addr.s_addr = inet_addr(ip);
local.sin_port = htons(port);
if(bind(sock, (struct sockaddr*)&local, sizeof(local))< 0)
{
perror("bind");
return 2;
}
if(listen(sock, 5) < 0)
{
perror("listen");
return 3;
}
return sock;
}
void Usage(char* proc)
{
printf("usage: %s [local_ip] [local_port]",proc);
}
int main(int argc, char* argv[])
{
if(argc != 3)
{
Usage(argv[0]);
return 1;
}
int listen_sock = statup(atoi(argv[2]), argv[1]);
struct sockaddr_in peer;
int len = sizeof(peer);
while(1)
{
int sock = accept(listen_sock, (struct sockaddr*)&peer, &len);
if(sock < 0)
{
perror("accept");
return 2;
}
pthread_t tid;
int ret = pthread_create(&tid, NULL, handle_fd, &sock);
if(ret != 0)
{
perror("pthread_create");
return 3;
}
printf("get client ip:%s port:%d\n",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port));
// pthread_join(tid,NULL);
pthread_detach(tid);
// close(sock);
}
return 0;
}
client.c
作用:链接server,并向server发起通信请求
/*************************************************************************
> File Name: client.c
> Author: ZX
> Mail: 18829897183@163.com
> Created Time: Tue 07 Mar 2017 10:46:28 PM PST
************************************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>
static void usage(char* porc)
{
printf("Usage: %s [ip] [port]\n",porc);
}
int main(int argc, char* argv[])
{
if(argc != 3)
{
usage(argv[0]);
return 1;
}
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
perror("sock");
return 2;
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(argv[1]);
server.sin_port = htons(atoi(argv[2]));
socklen_t len = sizeof(server);
if(connect(sock, (struct sockaddr*)&server, len) < 0)
{
perror("connect");
return 3;
}
char buf[1024];
while(1)
{
ssize_t s = read(0, buf, sizeof(buf)-1);
buf[s-1] = 0;
printf("%s\n",buf);
fflush(stdout);
write(sock, buf, sizeof(buf)-1);
}
close(sock);
return 0;
}
Makefile:
.PHONY:all
all:tserver client
client:client.c
gcc -o $@ $^ -lpthread
tserver:tserver.c
gcc -o $@ $^ -lpthread
.PHONY:clean
clean:
rm -f tserver client
运行结果: