学习网络编程,得有点东西交出来才行,所以贴一份自己写的通讯工具代码,仅仅是最基本的实现,大神勿喷。
服务器段代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/select.h>
#define MAXLINE 4096
#define SERV_PORT 5000
#define LISTENQ 5
int main(int argc, char **argv)
{
int listenfd, connfd, maxfd;
struct sockaddr_in cliaddr, servaddr;
socklen_t clilen;
char recvline[MAXLINE], sendline[MAXLINE];
ssize_t nread;
const char *quit_code = "quit\n";
fd_set rset;
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return -1;
}
memset(&servaddr, 0x00, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
perror("bind");
return -1;
}
if (listen(listenfd, LISTENQ) < 0) {
perror("listen");
return -1;
}
clilen = sizeof(cliaddr);
if ((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen)) < 0) {
perror("accept");
}
maxfd = connfd > fileno(stdin) ? connfd + 1 : fileno(stdin) + 1;
for(;;) {
FD_ZERO(&rset);
FD_SET(fileno(stdin), &rset);
FD_SET(connfd, &rset);
if (select(maxfd, &rset, NULL, NULL, NULL) < 0) {
perror("select");
continue;
}
if (FD_ISSET(connfd, &rset)) {
memset(recvline, 0x00, MAXLINE);
nread = read(connfd, recvline, MAXLINE);
if (nread <= 0) {
perror("read from connfd");
continue;
} else {
if (strcasecmp(recvline, quit_code) == 0) {
printf("client input quit, server will exit\n");
break;
} else {
if (write(fileno(stdout), recvline, nread) < 0) {
perror("write to stdout");
continue;
}
}
}
}
if (FD_ISSET(fileno(stdin), &rset)) {
memset(sendline, 0x00, MAXLINE);
nread = read(fileno(stdin), sendline, MAXLINE);
if (nread < 0) {
perror("read from stdin");
continue;
} else if (nread == 0) {
printf("read EOF, server will exit\n");
break;
} else {
if (strcasecmp(sendline, quit_code) == 0) {
printf("server input quit code, server will exit\n");
break;
} else {
if (write(connfd, sendline, nread) < 0) {
perror("write to connfd");
continue;
}
}
}
}
}
write(connfd, quit_code, strlen(quit_code) + 1);
return 0;
}
客户端代码如下:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#define MAXLINE 4096
#define SERV_PORT 5000
int main(int argc, char **argv)
{
int sockfd, maxfd;
struct sockaddr_in servaddr;
ssize_t nread;
char recvline[MAXLINE], sendline[MAXLINE];
const char *quit_code = "quit\n";
fd_set rset;
if (argc != 2) {
printf("imcli1 <IPaddress>\n");
return -1;
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return -1;
}
memset(&servaddr, 0x00, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) < 0) {
perror("inet_pton");
return -1;
}
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
perror("connect");
return -1;
}
maxfd = sockfd > fileno(stdin) ? sockfd + 1 : fileno(stdin) + 1;
for (;;) {
FD_ZERO(&rset);
FD_SET(fileno(stdin), &rset);
FD_SET(sockfd, &rset);
if (select(maxfd, &rset, NULL, NULL, NULL) < 0) {
perror("select");
continue;
}
if (FD_ISSET(fileno(stdin), &rset)) {
memset(sendline, 0x00, MAXLINE);
nread = read(fileno(stdin), sendline, MAXLINE);
if (nread < 0) {
perror("read from stdin");
continue;
} else if (nread == 0) {
printf("read EOF, client will exit\n");
break;
} else {
if (strcasecmp(sendline, quit_code) == 0) {
printf("client input quit code, client will exit\n");
break;
} else {
if (write(sockfd, sendline, nread) <= 0) {
perror("write to sockfd");
continue;
}
}
}
}
if (FD_ISSET(sockfd, &rset)) {
memset(recvline, 0x00, MAXLINE);
nread = read(sockfd, recvline, MAXLINE);
if (nread <= 0) {
perror("read from sockfd");
continue;
} else {
if (strcasecmp(recvline, quit_code) == 0) {
printf("server input quit code, client will exit\n");
break;
} else {
if (write(fileno(stdout), recvline, nread) <= 0) {
perror("write to stdout");
continue;
}
}
}
}
}
write(sockfd, quit_code, strlen(quit_code) + 1);
return 0;
}
总共差不多200行的代码量,其实不难,大家可以自己动手试试。