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>
#include <fcntl.h>
/* 伺服器要監聽的本地連接埠 */
#define MYPORT 4000
/* 能夠同時接受多少沒有accept 的串連 */
#define BACKLOG 10
//void sig_urg(int signo);
int main()
{
int sock_fd, new_fd,fd;
/* 自己的地址資訊 */
struct sockaddr_in my_addr;
/* 串連者的地址資訊*/
struct sockaddr_in their_addr;
int sin_size;
int n;
char buff[2281]={0};
/* 這裡就是我們一直強調的錯誤檢查.如果調用socket() 出錯,則返回 */
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/* 輸出錯誤提示並退出 */
perror("socket");
exit(1);
}
/* 主機位元組順序 */
my_addr.sin_family = AF_INET;
/* 網路位元組順序,短整型 */
my_addr.sin_port = htons(MYPORT);
/* 將運行程式機器的IP 填充入s_addr */
my_addr.sin_addr.s_addr = INADDR_ANY; // 用戶端ip
/* 將此結構的其餘空間清零 */
bzero(&(my_addr.sin_zero), 8);
/* 這裡是我們一直強調的錯誤檢查!! */
if (bind(sock_fd, (struct sockaddr *)&my_addr,sizeof(struct sockaddr)) == -1)
{
/* 如果調用bind()失敗,則給出錯誤提示,退出 */
perror("bind");
exit(1);
}
/* 這裡是我們一直強調的錯誤檢查!! */
if (listen(sock_fd, BACKLOG) == -1)
{
/* 如果調用listen 失敗,則給出錯誤提示,退出 */
perror("listen");
exit(1);
}
///* 設定SIGURG 的處理函數 sig_urg */
//old_sig_urg_handle = signal(SIGURG, sig_urg);
///* 更改connfd 的屬主 */
//fcntl(sock_fd, F_SETOWN, getpid());
while(1)
{
/* 這裡是主accept()迴圈 */
sin_size = sizeof(struct sockaddr_in);
/* 這裡是我們一直強調的錯誤檢查!! */
if ((new_fd = accept(sock_fd,(struct sockaddr *)&their_addr,&sin_size)) == -1)
{
/* 如果調用accept()出現錯誤,則給出錯誤提示,進入下一個迴圈 */
perror("accept");
continue;
}
/* 伺服器給出出現串連的資訊 */
printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr));
printf("buff:%s\n",buff);
/* 這裡將建立一個子進程來和剛剛建立的通訊端進行通訊 */
if (!fork())
{
/* 這裡是子進程 */
while(1)
{
if((n=recv(new_fd, buff, (sizeof(buff)-1),0 ))==0)
{
printf("received EOF\n");
break ;
}
buff[n] = 0 ;
printf("Recv %d bytes: %s\n", n, buff);
fd=open("test.jpg",O_RDWR|O_CREAT,0777);
write(fd,buff,sizeof(buff));
close(fd);
}
/* 關閉new_fd 代表的這個通訊端串連 */
close(new_fd);
}
}
return 0;
}
///* 等待所有的子進程都退出 */
//while(waitpid(-1,NULL,WNOHANG) > 0);
///* 恢複系統以前對SIGURG 的處理器 */
//signal(SIGURG, old_sig_urg_handle);
//}
//void sig_urg(int signo)
//{
//int n;
//char buff[100] ;
//printf(“SIGURG received\n”);
//n = recv(new_fd, buff, sizeof(buff)– 1, MSG_OOB);
//buff [ n ] = 0 ;
//printf(“recv %d OOB byte: %s\n” , n, buff);
//}
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>
#include <fcntl.h>
/* 伺服器程式監聽的連接埠號碼 */
#define PORT 4000
/* 我們一次所能夠接收的最大位元組數 */
#define MAXDATASIZE 2280 //該數若小於圖片的大小,則傳輸的映像是不完整的
int main(int argc, char *argv[])
{
int sockfd, numbytes,fd;
char buf[MAXDATASIZE]={0};
struct hostent *he;//伺服器資訊
/* 串連者用戶端的主機資訊 */
struct sockaddr_in their_addr;
/* 檢查參數資訊 */
if (argc != 2)
{
/* 如果沒有參數,則給出使用方法後退出 */
fprintf(stderr,"usage: client hostname\n");
exit(1);
}
/* 取得主機資訊 */
if ((he=gethostbyname(argv[1])) == NULL)
{
/* 如果gethostbyname()發生錯誤,則顯示錯誤資訊並退出 */
perror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/* 如果socket()調用出現錯誤則顯示錯誤資訊並退出 */
perror("socket");
exit(1);
}
//用戶端填寫伺服器端得資訊
bzero(&(their_addr.sin_zero), sizeof(their_addr));
/* 主機位元組順序 */
their_addr.sin_family = AF_INET;
/* 網路位元組順序,短整型 */
their_addr.sin_port = htons(PORT);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
if(connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
{
/* 如果connect()建立串連錯誤,則顯示出錯誤資訊,退出 */
perror("connect");
exit(1);
}
fd=open("8k.jpg",O_RDWR);
read(fd,buf,MAXDATASIZE);
if (send(sockfd, buf, MAXDATASIZE, 0) == -1)
{
/* 如果錯誤,則給出錯誤提示,然後關閉這個新串連,退出 */
perror("send");
close(sockfd);
exit(0);
}
printf("Send 3 byte of normal data\n");
//sleep(1);
/*
if(send(sockfd,"4",1,MSG_OOB)== -1)
{
perror("send");
close(sockfd);
exit(0);
}
printf("Send 1 byte of OOB data\n");
sleep(1);
if (send(sockfd, "56", 2, 0) == -1)
{
perror("send");
close(sockfd);
exit(0);
}
printf("Send 2 bytes of normal data\n");
sleep(1);
if (send(sockfd, "7", 1, MSG_OOB)== -1)
{
perror("send");
close(sockfd);
exit(0);
}
printf("Send 1 byte of OOB data\n");
sleep(1);
if (send(sockfd, "89", 2, MSG_OOB)==-1)
{
perror("send");
close(sockfd);
exit(0);
}
printf("Send 2 bytes of normal data\n");
//*/
sleep(1);
close(fd);
close(sockfd);
return 0;
}