Linux基於TCP/IP簡單的客戶端、伺服器通訊程式例項
伺服器端程式碼:
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<sys/socket.h>
#include<resolv.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<fcntl.h>
int main (int argc, char * argv[])
{
//建立套接字,即建立socket
int server_sockfd, client_sockfd;
unsigned int myport;
socklen_t len;
struct sockaddr_in server_addr, client_addr;
char buf[1024];
//繫結資訊,即命名socket
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(myport);
if (argc !=3 )
{
printf("Please Input %s IP Port\n",argv[0]);
exit(EXIT_FAILURE);
}
//inet_addr函式將用點分十進位制字串表示的IPv4地址轉化為用網路位元組序整數表示的IPv4地址
if(argv[1])
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
else
server_addr.sin_addr.s_addr = INADDR_ANY;
if(argv[2])
myport = atoi(argv[2]);
else
myport = 7575;
//建立socket
if((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket");
return 1;
}
//繫結
if(bind(server_sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
{
perror("bind");
return 2;
}
//監聽socket
if(listen(server_sockfd, 5) < 0)
{
perror("listen");
return 3;
}
//int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen)
//sockfd引數是執行過listen系統呼叫的監聽socket;addr引數用來獲取被
//接受連線的遠端socket地址,該socket地址的長度由addrlen引數指出
//accept成功時返回一個新的連線socket,該socket唯一的標識了被接受
//的這個連線,伺服器可通過讀寫該socket來與被接受連線對應的客戶端通訊
len = sizeof(struct sockaddr);
client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_addr, (socklen_t *)&len);
if(client_sockfd < 0)
{
perror("accept");
return 4;
}
else
{
printf("connected with IP: %s and port: %d\n", inet_ntop(AF_INET,&client_addr.sin_addr, buf, 1024), ntohs(client_addr.sin_port));
}
printf("Waiting client connecting……");
while(1)
{
memset(buf, '\0', sizeof(buf));
ssize_t size = read(client_sockfd, buf, sizeof(buf) - 1);
if(size > 0)
{
printf("client#: %s\n", buf);
}
else if(size == 0)
{
printf("read is done...\n");
break;
}
else
{
perror("read");
break;
}
printf("server please enter: ");
fflush(stdout); //重新整理標準輸出緩衝區,把輸出緩衝區裡的東西列印到標準輸出裝置上
size = read(0, buf, sizeof(buf) - 1);
if(size > 0)
{
buf[size - 1] = '\0';
}
else if(size == 0)
{
printf("read is done...\n");
break;
}
else
{
perror("read");
break;
}
write(client_sockfd, buf, strlen(buf));
}
close(server_sockfd);
return 0;
}
客戶端程式碼:
#include <stdio.h>#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main (int argc, char * argv[])
{
unsigned int myport;
int client_sockfd;
//建立套接字,即建立socket
if (argc !=3 )
{
printf("Please Input %s IP Port\n",argv[1]);
exit(EXIT_FAILURE);
}
client_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(client_sockfd < 0)
{
perror("socket");
return 1;
}
//繫結資訊,即命名socket
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(argv[2]));
//inet_addr函式將用點分十進位制字串表示的IPv4地址轉化為用網路
//位元組序整數表示的IPv4地址
addr.sin_addr.s_addr = inet_addr(argv[1]);
//不需要監聽
//發起連線
// struct sockaddr_in peer;
socklen_t addr_len = sizeof(addr);
int connect_fd = connect(client_sockfd, (struct sockaddr*)&addr, addr_len);
if(connect_fd < 0)
{
perror("connect");
return 2;
}
char buf[1024];
while(1)
{
memset(buf, '\0', sizeof(buf));
printf("client please enter: ");
fflush(stdout);
ssize_t size = read(0, buf, sizeof(buf) - 1);
if(size > 0)
{
buf[size - 1] = '\0';
}
else if(size == 0)
{
printf("read is done...\n");
break;
}
else
{
perror("read");
return 4;
}
// printf("client: %s\n", buf);
write(client_sockfd, buf, strlen(buf));
size = read(client_sockfd, buf, sizeof(buf));
if(size > 0)
{
buf[size] = '\0';
}
else if(size == 0)
{
printf("read is done...\n");
break;
}
else
{
perror("read");
return 5;
}
printf("server: %s\n", buf);
}
close(client_sockfd);
return 0;
}