服务端:
/*************************************************************************
> File Name: server.c
> Author: ma6174
> Mail: ma6174@163.com
> Created Time: 2020年08月02日 星期日 14时44分18秒
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <pthread.h>
#include <malloc.h>
const int N = 128;
static int num = 0;
struct node{
struct sockaddr_in addr;
int clientfd;
};
void sys_err(char *msg)
{
perror(msg);
exit(1);
}
void *do_work(void *arg)
{
struct node *vel = (struct node*) arg;
char buf[N];
printf("new client join ip:%s port:%d number:%d\n",inet_ntoa(vel->addr.sin_addr),
ntohs(vel->addr.sin_port),++num);
memset(buf,'\0',sizeof(buf));
while(1)
{
int ret = read(vel->clientfd,buf,N);
if(ret != 0)
printf("[ip : %s -- port : %d] data : %s\n",inet_ntoa(vel->addr.sin_addr),
ntohs(vel->addr.sin_port),buf);
else {
printf("[ip : %s -- port : %d] is exit\n",inet_ntoa(vel->addr.sin_addr),
ntohs(vel->addr.sin_port));
break;
}
write(vel->clientfd,"Accept",N);
}
close(vel->clientfd);
free(vel);
return NULL;
}
int main(int argc, char const *argv[])
{
if(argc < 3) sys_err("input error");
int sfd,cfd;
pthread_t rid;
sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd == -1) sys_err("Create socket error");
struct sockaddr_in server_addr,client_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));
socklen_t slen = sizeof(server_addr);
int val = 1; //加上这个能很好的解决端口复用的问题
int ret = setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(int));
if(ret == -1)
sys_err("setsockopt error"),close(sfd);
if(bind(sfd,(struct sockaddr*)&server_addr,slen) == -1)
sys_err("bind error"),close(sfd);
if(listen(sfd,N) == -1)
sys_err("listen error"),close(sfd);
socklen_t clen = sizeof(client_addr);
while(1)
{
cfd = accept(sfd,(struct sockaddr*)&client_addr,&clen);
if(cfd == -1) sys_err("accept error"),close(sfd);
struct node *a;
a = (struct node*)malloc(sizeof(struct node));
a->addr = client_addr;
a->clientfd = cfd;
if(pthread_create(&rid,NULL,(void *)do_work,(void *)a) != 0)
sys_err("pthread create"),close(sfd);
pthread_detach(rid);
}
close(sfd);
return 0;
}
客户端:
/*************************************************************************
> File Name: client.c
> Author: ma6174
> Mail: ma6174@163.com
> Created Time: 2020年08月01日 星期六 17时39分40秒
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#define N 128
int main(int argc, char const *argv[])
{
if(argc < 3) {
perror("input ip and port\n");
exit(1);
}
int sockfd;
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
fprintf(stdout,"Create socket error\n");
exit(1);
}
struct sockaddr_in client_addr;
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = inet_addr(argv[1]);
client_addr.sin_port = htons(atoi(argv[2]));
if(connect(sockfd,(struct sockaddr*)&client_addr,sizeof(client_addr)) == -1)
{
perror("connect error\n");
exit(1);
}
char buf[N];
char recv_buf[N];
memset(buf,'\0',sizeof(buf));
while(fgets(buf,N,stdin) != NULL)
{
memset(recv_buf,'\0',sizeof(recv_buf));
write(sockfd,buf,strlen(buf));
read(sockfd,recv_buf,sizeof(recv_buf));
printf("server : %s\n",recv_buf);
memset(buf,'\0',sizeof(buf));
}
close(sockfd);
return 0;
}
Makefile:
CC = gcc
CFLAGS = -lm -Wall -g
all:server client
server:server.o
$(CC) $(CFLAGS) -pthread server.o -o server
client:client.o
$(CC) $(CFLAGS) client.o -o client
server.o:server.c
$(CC) $(CFLAGS) -c -pthread server.c -o server.o
client.o:client.c
$(CC) $(CFLAGS) -c client.c -o client.o
clear:
rm *.o
测试结果: