題目:Hello world
要求:案常式序基於TCP協議,由客戶程式啟動後向伺服器程式發送“hello world”,伺服器程式顯示客戶機IP地址、連接埠、以及發送的資訊。伺服器將收到的字串發送給用戶端,用戶端顯示驗證。
使用方法:在linux下編譯
$gcc -o client client.c
$gcc -o server server.c
先運行server程式$./server
再運行client程式$./client xxx(你要訪問伺服器名---非IP)
程式:
/* client.c */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main(int argc,char *argv[]) {
int sockfd,numbytes;
char buf[100];
char *msg="hello world";
struct hostent *he;
struct sockaddr_in their_addr;
int i = 0;
//將基本名字和地址轉換,使用者必須輸入伺服器的名字為參數
if(argc<2) {
printf("You should input IP or Name of the server!\n");
exit(1);
}
he = gethostbyname(argv[1]);
//建立一個TCP套介面
if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1) {
perror("socket");
exit(1);
}
//初始化結構體,串連到伺服器的2323連接埠
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(2323);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero),8);
//和伺服器建立串連,若串連建立失敗則直接報錯
if(connect(sockfd,(struct sockaddr *)&their_addr,
sizeof(struct sockaddr))==-1){
perror("connect");
exit(1);
}
//向伺服器發送字串msg
if(send(sockfd,msg,strlen(msg),0)==-1) {
perror("send");
exit(1);
}
//接受從伺服器返回的資訊
if((numbytes = recv(sockfd,buf,100,0))==-1) {
perror("recv");
exit(1);
}
buf[numbytes] = '\0';
printf("result:%s",buf);
close(sockfd);
return 0;
}
/* server.c */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
void showClientInf(struct sockaddr_in client_addr) {
printf("\nThe IP of client is:%s",inet_ntoa(client_addr.sin_addr));
printf("\nThe Port of client is:%d\n",ntohs(client_addr.sin_port));
}
int main() {
int sockfd,new_fd;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
int sin_size;
char buff[100];
int numbytes;
//建立TCP套介面
if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1) {
perror("socket");
exit(1);
}
//初始化結構體,並綁定2323連接埠
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(2323);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
//綁定套介面
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
//建立監聽套介面
if(listen(sockfd,10)==-1) {
perror("listen");
exit(1);
}
printf("server is run...\n");
//等待串連
while(1) {
sin_size = sizeof(struct sockaddr_in);
//如果建立串連,將產生一個全新的通訊端,their_fd儲存發送方的資訊
//一個通訊端與用戶端保持控制串連,新通訊端與用戶端傳遞、接受資訊
if((new_fd = accept(sockfd,(struct sockaddr *)
&their_addr,&sin_size))==-1)
{
perror("accept");
exit(1);
}
//顯示用戶端資訊
showClientInf(their_addr);
//產生一個子進程來完成和用戶端的會話,父進程繼續監聽
if(!fork()) {
//讀取用戶端發來的資訊
//只能用sizeof取buff的大小,因為buff還沒初始化,用strlen很容易碰到'\0'
if((numbytes = recv(new_fd,buff,sizeof(buff),0))==-1)
{
perror("recv");
exit(1);
}
buff[numbytes]='\0';
printf("recieved %d bytes.\n",numbytes);
printf("the message is:%s\n",buff);
//將從用戶端接收到的資訊再發回用戶端
if(send(new_fd,buff,strlen(buff),0)==-1)
perror("send");
close(new_fd);
exit(0);
}
close(new_fd);
}
close(sockfd);
}
打包下載:
http://files.cnblogs.com/lzcarl/tcp.rar