socket example

# UTF-8

服务端程序源文件为server/server.c
客户端程序源文件为client/client.c

分别进入server和client目录后执行make即可生成server和client应用
首先开启server,然后再另一个中断打开client即可连接到server

/*
 * server
 * */
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

int sockfd;
char* IP = "127.0.0.1";//服务端的IP
short PORT = 10111;
typedef struct sockaddr SA;
char dir_name[20] = "files";
char rcvmsg[256] = { 0 };	//recieve client message

/* 1服务端初始化网络,开放端口*/
void init()
{
	printf("Server starting...\n");
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1) {
		perror("socket");
		exit(-1);
	}
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);
	addr.sin_addr.s_addr = inet_addr(IP);

	//solve "address already in use" issue
	int reuseaddr = 1;
	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
		   sizeof(reuseaddr));

	if (bind(sockfd, (SA *) & addr, sizeof(addr)) == -1) {
		perror("bind");
		exit(-1);
	}

	if (listen(sockfd, 100) == -1) {
		perror("listen");
		exit(-1);
	}
	printf("Server init OK!\n");
}

/* 接收client message的函数 */
void rcv_proc(int sfd)
{
	int size = 0;
	char buf[512] = { };
	while (size = read(sfd, buf, sizeof(buf))) {
		printf("Client %d say>: %s", sfd, buf);
		if (!write(sfd, buf, strlen(buf) + 1)) {
			perror("write");
		}
		memset(buf, 0, 100);
	}
	printf("%d has disconnect!\n", sfd);
}

//2处理客户端的连接
void service()
{
	printf("Server has started!\n");
	while (1) {
		struct sockaddr_in fromaddr;
		socklen_t len = sizeof(fromaddr);
		printf("\nWaitint for clients to connect...\n");
		int fd = accept(sockfd, (SA *) & fromaddr, &len);
		if (fd == -1) {
			printf("Client connect failed!\n");
			continue;	//继续处理下一个连接
		} else {
			printf("Has connect to client: %d\n", fd);
		}
		rcv_proc(fd);
	}
}

void sig_close()
{
	close(sockfd);
	printf("Server is going down...\n");
	exit(0);
}

int main()
{
	signal(SIGINT, sig_close);	//定义信号处理函数
	printf("Press <Ctrl+C> to stop server.\n");
	//初始化网络
	init();
	//启动服务
	service();
	return 0;
}

CC=gcc
OBJS=server
CFLAGS=-o
SRC=server.c

OBJS: $(SRC)
	$(CC) $(SRC) $(CFLAGS) $(OBJS)

clean:
	-rm -rv $(OBJS) 

client

/*
 * client
 * */
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int sockfd;
char* IP="127.0.0.1";//对方的IP
short PORT=10111;
typedef struct sockaddr SA;
char name[20];//用于存放文件名

/* 1启动客户端,连接服务器*/
void init()
{
	printf("client starting...\n");
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);
	addr.sin_addr.s_addr = inet_addr(IP);
	if(connect(sockfd, (SA*)&addr, sizeof(addr)) == -1){
            perror("Can not connect to server.");
            printf("Client start failed!\n");
            exit(-1);
	}
	printf("Client start successed!\n");
	printf("Type <q> to exit.\n");
}

int get_user_input(char *str, int size)
{
	printf("Client>: ");
	fgets(str, size, stdin);
	return strlen(str);
}

/* 2通信 */
void start()
{
    int size = 0;
    char msg[100] = {};    
    char str[100] = {};
    do {
        memset(msg, 0, sizeof(msg));
        size = get_user_input(msg, sizeof(msg));
        printf("Send message to Server: %s", msg);
        write(sockfd, msg, size + 1);
        read(sockfd, str, sizeof(msg));
        printf("Server return message: %s", str);
        if (!strcmp(msg, "bye\n"))
        {
            exit(0);
        }
    } while(1);
    close(sockfd);
}
int main()
{
    init();//连接服务器
    start();//发送
    return 0;
}

CC=gcc
OBJS=client
CFLAGS=-o
SRC=client.c

OBJS: $(SRC)
	$(CC) $(SRC) $(CFLAGS) $(OBJS)

clean:
	-rm -vf $(OBJS)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值