很早的一段时间,看了APUE和UNPv1了解了网络编程,但是但是只是看而已,没有具体的实践,趁现在没有什么事做,就来实践了解一下网络编程。写博客保存下来,方便以后用到的时候可以查到。
此次的聊天程序是迭代开发的。就是一步一步的修改成不同功能的聊天程序。
服务器server和客户端client
一对一,server和client是每人一句话聊天
讲解几个函数gethostbyname(),这个函数以前讲过就不多说了。
socket函数
#include <sys/socket.h>
int socket(int domain, int type, int protocol); //返回值:若成功则返回文件(套接字)描述符,若出错则返回-1
connect函数
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t len); //返回值:若成功则返回0,若出错则返回-1
bind函数
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t len); //返回值:若成功则返回0,若出错则返回-1
listen函数
#include <sys/socket.h>
int listen(int sockfd, int backlog); //返回值:若成功则返回0,若出错则返回-1,backlog表示连接请求数量
accept函数
#include <sys/socket.h>
int accept(int socdfd, struct sockaddr *restrict addr, socklen_t * restrict len); //若成功则返回文件(socket套接字)描述符,若出错则返回-1
recv函数
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags); //返回值:以字节计数的消息长度,若无可用消息或对方已经按序结束则返回0,若出错则返回-1
send函数
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags); //返回值:若成功则返回发送的字节数,若出错则返回-1
fgets函数
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
介绍完函数后,就直接贴出代码。
client.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h> //for gethostbyname
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> #define MAX_BUF 4096
#define SERVER_PORT 12138 int main(int argc,char *argv[])
{
int sockfd;//socket
char sendBuf[MAX_BUF],recvBuf[MAX_BUF];
int sendSize,recvSize;//用于记录记录发送和接收到数据的大小
struct hostent * host;
struct sockaddr_in servAddr;
char username[];
char * p; if(argc != )
{
perror("use: ./client [hostname] [username]");
exit(-);
}
p=username;
strcpy(p,argv[]);
printf("username:%s\n",username);
host=gethostbyname(argv[]);
if(host==NULL)
{
perror("fail to get host by name.");
exit(-);
}
printf("Success to get host by name ...\n"); //创建socket
if((sockfd=socket(AF_INET,SOCK_STREAM,))==-)
{
perror("fail to establish a socket");
exit();
}
printf("Success to establish a socket...\n"); /*init sockaddr_in*/
servAddr.sin_family=AF_INET;
servAddr.sin_port=htons(SERVER_PORT);
servAddr.sin_addr=*((struct in_addr *)host->h_addr);
bzero(&(servAddr.sin_zero),); /*connect the socket*/
if(connect(sockfd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr_in))==-)
{
perror("fail to connect the socket");
exit();
}
printf("Success to connect the socket...\n"); //send-recv
while()
{
printf("Input:");
fgets(sendBuf,MAX_BUF,stdin);
send(sockfd,sendBuf,strlen(sendBuf),);
memset(sendBuf,,sizeof(sendBuf));
recv(sockfd,recvBuf,MAX_BUF,);
printf("Server:%s\n",recvBuf);
memset(recvBuf,,sizeof(recvBuf));
} return ;
}
server.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h> #define SERVER_PORT 12138
#define BACKLOG 20
#define MAX_CON_NO 10
#define MAX_DATA_SIZE 4096 int main(int argc,char *argv[])
{
struct sockaddr_in serverSockaddr,clientSockaddr;
char sendBuf[MAX_DATA_SIZE],recvBuf[MAX_DATA_SIZE];
int sendSize,recvSize;
int sockfd,clientfd;
int on=;
int sinSize=;
char username[]; if(argc != )
{
printf("usage: ./server [username]\n");
exit();
}
strcpy(username,argv[]);
printf("username:%s\n",username); /*establish a socket*/
if((sockfd = socket(AF_INET,SOCK_STREAM,))==-)
{
perror("fail to establish a socket");
exit();
}
printf("Success to establish a socket...\n"); /*init sockaddr_in*/
serverSockaddr.sin_family=AF_INET;
serverSockaddr.sin_port=htons(SERVER_PORT);
serverSockaddr.sin_addr.s_addr=htonl(INADDR_ANY);
bzero(&(serverSockaddr.sin_zero),); setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); /*bind socket*/
if(bind(sockfd,(struct sockaddr *)&serverSockaddr,sizeof(struct sockaddr))==-)
{
perror("fail to bind");
exit();
}
printf("Success to bind the socket...\n"); /*listen on the socket*/
if(listen(sockfd,BACKLOG)==-)
{
perror("fail to listen");
exit();
} /*accept a client's request*/
if((clientfd=accept(sockfd,(struct sockaddr *)&clientSockaddr, &sinSize))==-)
{
perror("fail to accept");
exit();
}
printf("Success to accpet a connection request...\n");
printf(" %s join in!\n",inet_ntoa(clientSockaddr.sin_addr));
while()
{
/*receive datas from client*/
if((recvSize=recv(clientfd,recvBuf,MAX_DATA_SIZE,))==-)
{
perror("fail to receive datas");
exit();
}
printf("%s\n",recvBuf);
memset(recvBuf,,MAX_DATA_SIZE); /*send datas to client*/
printf("Server:");
fgets(sendBuf,MAX_DATA_SIZE,stdin);
if((sendSize=send(clientfd,sendBuf,strlen(sendBuf),))!=strlen(sendBuf))
{
perror("fail to send datas");
exit();
}
printf("Success to send datas\n");
memset(sendBuf,,MAX_DATA_SIZE);
} return ;
}
这些代码都比较简单,详细的讲解网上都有,这里就不多说了。