linux socket编程,linux下socket 网络编程(客户端向服务器端发送文件) 求源代码 大哥大姐帮帮忙 。。谢谢
linux socket编程,linux下socket 网络编程(客户端向服务器端发送文件) 求源代码 大哥大姐帮帮忙 。。谢谢详细介绍
本文目录一览: 想做嵌入式linux平台上的cc开发,如何入手
二:Linux基础Linux操作系统的概念、安装方法,详细了解Linux下的目录结构、基本命令、编辑器VI,编译器GCC,调试器GDB和Make项目管理工具,ShellMakefile脚本编写等知识,嵌入式开发环境的搭建。
三:Linux系统编程重点学习标准I/O库,Linux多任务编程中的多进程和多线程,以及进程间通信(pipe、FIFO、消息队列、共享内存、signal、信号量等),同步与互斥对共享资源访问控制等重要知识,主要提升对Linux应用开发的理解和代码调试的能力。
四:Linux网络编程计算机网络在嵌入式Linux系统应用开发过程中使用非常广泛,通过Linux网络发展、TCP/IP协议、socket编程、TCP网络编程、UDP网络编程、Web编程开发等方面入手,全面了解Linux网络应用程序开发。重点学习网络编程相关API,熟练掌握TCP协议服务器的编程方法和并发服务器的实现,了解HTTP协议及其实现方法,熟悉UDP广播、多播的原理及编程方法,掌握混合C/S架构网络通信系统的设计,熟悉HTML,Javascript等Web编程技术及实现方法。
五:数据结构与算法数据结构及算法在嵌入式底层驱动、通信协议、及各种引擎开发中会得到大量应用,对其掌握的好坏直接影响程序的效率、简洁及健壮性。此阶段的学习要重点理解数据结构与算法的基础内容,包括顺序表、链表、队列、栈、树、图、哈希表、各种查找排序算法等应用及其C语言实现过程。
linux socket编程后是tcp还是udp
Linux socket编程既可以是TCP连接,也可以是UDP连接。Linux socket编程首先要用socket系统调用创建一个套接字,socket系统调用的原型是:
int socket(int domain, int type, int protocol);
当socket函数的type参数指定为SOCK_STREAM时,就相当于建立的是个TCP连接;当type参数指定为SOCK_DGRAM时,建立的就是一个UDP连接。当建立TCP或者UDP连接的时候,注意把第一个参数domain指定为AF_INET。
linux C语言编程,socket实现的即使通讯系统
//服务端server.c
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVPORT 6000 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */
#define MAXDATASIZE 100
main()
{
char buf[MAXDATASIZE];
int sockfd,client_fd; /*sock_fd:监听socket;client_fd:数据传输socket */
struct sockaddr_in my_addr; /* 本机地址信息 */
struct sockaddr_in remote_addr; /* 客户端地址信息 */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket创建出错!");
exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
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, BACKLOG) == -1)
{
perror("listen出错!");
exit(1);
}
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1)
{
perror("accept出错");
continue;
}
printf("received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));
if (!fork())
{ /* 子进程代码段 */
if ((recvbytes=recv(client_fd, buf, MAXDATASIZE, 0)) ==-1)
{
perror("recv出错!");
close(client_fd);
exit(0);
}
buf[recvbytes] = '\0';
printf("from client Received: %s",buf);
if (send(client_fd, "thanks!\n", 8, 0) == -1)
perror("send出错!");
close(client_fd);
exit(0);
}
close(client_fd);
}
}
//客户端client.c
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVPORT 6000
#define MAXDATASIZE 100
main(int argc, char *argv[])
{
int sockfd, recvbytes;
char buf[MAXDATASIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if (argc < 2)
{
fprintf(stderr,"Please enter the server's hostname!\n");
exit(1);
}
if((host=gethostbyname(argv[1]))==NULL)
{
herror("gethostbyname出错!");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket创建出错!");
exit(1);
}
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERVPORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero),8);
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1)
{
perror("connect出错!");
exit(1);
}
if (send(sockfd, "hello!\n", 7, 0) == -1)
{
perror("send出错!");
exit(1);
}
if ((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1)
{
perror("recv出错!");
exit(1);
}
buf[recvbytes] = '\0';
printf("Received: %s",buf);
close(sockfd);
}
//服务端server.c
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVPORT 6000 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */
#define MAXDATASIZE 100
main()
{
char buf[MAXDATASIZE];
int sockfd,client_fd; /*sock_fd:监听socket;client_fd:数据传输socket */
struct sockaddr_in my_addr; /* 本机地址信息 */
struct sockaddr_in remote_addr; /* 客户端地址信息 */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket创建出错!");
exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
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, BACKLOG) == -1)
{
perror("listen出错!");
exit(1);
}
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1)
{
perror("accept出错");
continue;
}
printf("received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));
if (!fork())
{ /* 子进程代码段 */
if ((recvbytes=recv(client_fd, buf, MAXDATASIZE, 0)) ==-1)
{
perror("recv出错!");
close(client_fd);
exit(0);
}
buf[recvbytes] = '\0';
printf("from client Received: %s",buf);
if (send(client_fd, "thanks!\n", 8, 0) == -1)
perror("send出错!");
close(client_fd);
exit(0);
}
close(client_fd);
}
}
//客户端client.c
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVPORT 6000
#define MAXDATASIZE 100
main(int argc, char *argv[])
{
int sockfd, recvbytes;
char buf[MAXDATASIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if (argc < 2)
{
fprintf(stderr,"Please enter the server's hostname!\n");
exit(1);
}
if((host=gethostbyname(argv[1]))==NULL)
{
herror("gethostbyname出错!");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket创建出错!");
exit(1);
}
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERVPORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero),8);
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1)
{
perror("connect出错!");
exit(1);
}
if (send(sockfd, "hello!\n", 7, 0) == -1)
{
perror("send出错!");
exit(1);
}
if ((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1)
{
perror("recv出错!");
exit(1);
}
buf[recvbytes] = '\0';
printf("Received: %s",buf);
close(sockfd);
}
Socket通信创建步骤:
(1)通过socket()函数创建socket(2)通过bind函数绑定socket于设备地址(3)进行读写操作read/recv/recvfrom write/send/sendto(4)close方法关闭套接字
例子如下:
test1.c
#include
#include
#include
#include
#include
int main(void) { //create socket int fd = socket(AF_INET, SOCK_DGRAM, 0); if(fd==-1) { perror("socket\n"); exit(-1); } printf("socket fd=%d\n",fd); //build connection address struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(6666); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); int r; r = bind(fd,(struct sockaddr*)&addr,sizeof(addr)); if(r==-1) { perror("bind"); close(fd); exit(-1); } printf("bind address successful!\n"); //accept or send message char buf[255]; struct sockaddr_in from; socklen_t len; len = sizeof(from); while(1) { r = recvfrom(fd,buf,sizeof(buf)-1,0,(struct sockaddr*)&from,&len); if(r>0) { buf[r]=0; printf("The message from %s is:%s\n",inet_ntoa(from.sin_addr),buf); } else { break; } } //close socket close(fd); return 0; }
test2.c
#include
#include
#include
#include
#include
#include
#include
int main(void) { //create socket int fd = socket(AF_INET,SOCK_DGRAM,0); if(fd==-1) { perror("socket"); exit(-1); } printf("create socket OK!\n"); //create an send address struct sockaddr_in addr={}; addr.sin_family = AF_INET; addr.sin_port = htons(6666); addr.sin_addr.s_addr=inet_addr("127.0.0.1"); //send the message to the specify address int r; char buf[255]; while(1) { r = read(0,buf,sizeof(buf)-1); if(r<=0) break; sendto(fd,buf,r,0,(struct sockaddr*)&addr,sizeof(addr)); } //close socket close(fd); return 0; }先运行test1.c,然后运行test2.c,在test2.c运行后输入内容,在test1.c所在终端中就会显示信息
运行结果如下:
linux下socket 网络编程(客户端向服务器端发送文件) 求源代码 大哥大姐帮帮忙 。。谢谢
#include
#include
#include
#include
#include
#include
#include
main()
{
int serverfd=socket(AF_INET,SOCK_STREAM,0);
if(serverfd==-1) printf("服务器socket建立失败:%m\n"),exit(-1);
printf("服务器socket建立成功!\n");
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(11112);
inet_aton("192.168.180.92",&addr.sin_addr);
int r=bind(serverfd,(struct sockaddr*)&addr,sizeof(addr));
if(r==-1) printf("绑定地址失败:%m\n"),exit(-1);
printf("绑定地址成功!\n");
r=listen(serverfd,10);
if(r==-1) printf("监听服务socket变化失败:%m\n"),exit(-1);
printf("监听服务器socket成功!\n");
struct sockaddr_in caddr;
socklen_t len;
while(1)
{
len=sizeof caddr;
int fd=accept(serverfd,(struct sockaddr*)&caddr,&len);
printf("有人连接:%s:%d\n",
inet_ntoa(caddr.sin_addr),
ntohs(caddr.sin_port));
}
}
这是服务器端的,客户端的只要去掉监听,连接,再把发送接收数据改一下,就能用了
server:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXDATASIZE 1024
#define SERVPORT 19999
#define BACKLOG 10
int SendFileToServ(const char *path, const char *FileName, const char *ip)
{
#define PORT 20002
int sockfd;
int recvbytes;
char buf[MAXDATASIZE];
char send_str[MAXDATASIZE];
char filepath[128] = {0};
struct sockaddr_in serv_addr;
FILE *fp;
sprintf(filepath, "%s%s", path, FileName);
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
return 1;
}
bzero(&serv_addr,sizeof(struct sockaddr_in));
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(PORT);
inet_aton(ip, &serv_addr.sin_addr);
int IErrCount = 0;
again:
if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1)
{
if (5 == IErrCount)
return 1;
IErrCount++;
perror("connect");
sleep(2);
goto again;
}
//if ((fp = fopen(FileName, "rb")) == NULL)
if ((fp = fopen(filepath, "rb")) == NULL)
{
perror("fopen ");
return 1;
}
recvbytes = write(sockfd, FileName, strlen(FileName));
recvbytes = read(sockfd, buf, MAXDATASIZE);
if (!memcmp(buf, "sendmsg", 7))
{
while(fgets(send_str, MAXDATASIZE, fp))
{
recvbytes = write(sockfd, send_str, strlen(send_str));
recvbytes = read(sockfd, buf, MAXDATASIZE);
if (recvbytes <= 0)
{
fclose(fp);
close(sockfd);
return 1;
}
if (memcmp(buf, "goon", 4))
{
fclose(fp);
close(sockfd);
return 1;
}
}
recvbytes = write(sockfd, "end", 3);
}
else
{
fclose(fp);
close(sockfd);
return 1;
}
memset(buf, 0, MAXDATASIZE);
if (read(sockfd, buf, MAXDATASIZE) <= 0)
{
close(sockfd);
return 2;
}
char *Eptr = "nginx reload error";
//printf("bf[%s]\n", buf);
int ret;
ret = strncmp(buf, Eptr, strlen(Eptr));
//printf("%d\n", ret);
if (!ret)
{
close(sockfd);
return 2;
}
close(sockfd);
return 0;
}
int mysyslog(const char * msg)
{
FILE *fp;
if ((fp = fopen("/tmp/tmp.log", "a+")) == NULL)
{
return 0;
}
fprintf(fp, "[%s]\n", msg);
fclose(fp);
return 0;
}
static void quit_handler(int signal)
{
kill(0, SIGUSR2);
syslog( LOG_NOTICE, "apuserv quit...");
// do something exit thing ,such as close socket ,close mysql,free list
// .....
//i end
exit(0);
}
static int re_conf = 0;
static void reconf_handler(int signal)
{
re_conf=1;
syslog(LOG_NOTICE,"apuserv reload configure file .");
// 请在循环体中判断,如果re_conf == 1,请再次加载配置文件。
}
static int isrunning(void)
{
int fd;
int ret;
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = 0;
lock.l_start = 0;
lock.l_len = 0;
const char *lckfile = "/tmp/apuserv.lock";
fd = open(lckfile,O_WRONLY|O_CREAT);
if (fd < 0) {
syslog(LOG_ERR,"can not create lock file: %s\n",lckfile);
return 1;
}
if ((ret = fcntl(fd,F_SETLK,&lock)) < 0) {
ret = fcntl(fd,F_GETLK,&lock);
if (lock.l_type != F_UNLCK) {
close(fd);
return lock.l_pid;
}
else {
fcntl(fd,F_SETLK,&lock);
}
}
return 0;
}
int MyHandleBuff(const char *buf, char *str, char *FileName, char *pth)
{
sscanf(buf, "%s %s %s", pth, FileName, str);
printf("path=%s\nfilename=%s\nip=%s\n", pth, FileName, str);
return 0;
}
int main(int argc, char **argv)
{
int sockfd,client_fd;
socklen_t sin_size;
struct sockaddr_in my_addr,remote_addr;
char buff[MAXDATASIZE];
int recvbytes;
#if 1
int pid ;
char ch ;
int ret;
int debug = 0;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, quit_handler);
syslog(LOG_NOTICE,"apuserver start....");
while ((ch = getopt(argc, argv, "dhV")) != -1) {
switch (ch) {
case 'd':
debug = 1;
break;
case 'V':
printf("Version:%s\n","1.0.0");
return 0;
case 'h':
printf(" -d use daemon mode\n");
printf(" -V show version\n");
return 0;
default:
printf(" -d use daemon mode\n");
printf(" -V show version\n");
}
}
if (debug && daemon(0,0 ) ) {
return -1;
}
if (isrunning()) {
fprintf(stderr, "apuserv is already running\n");
syslog(LOG_INFO,"apuserv is already running\n");
exit(0);
}
while (1) {
pid = fork();
if (pid < 0)
return -1;
if (pid == 0)
break;
while ((ret = waitpid(pid, NULL, 0)) != pid) {
syslog(LOG_NOTICE, "waitpid want %d, but got %d", pid, ret);
if (ret < 0)
syslog(LOG_NOTICE, "waitpid errno:%d", errno);
}
kill(0, SIGUSR2);
sleep(1);
syslog(LOG_NOTICE,"restart apuserver");
}
signal(SIGHUP, reconf_handler);
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1,SIG_IGN);
signal(SIGUSR2, SIG_DFL);
signal(SIGTERM, SIG_DFL);
#endif
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
bzero(&my_addr,sizeof(struct sockaddr_in));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
if(listen(sockfd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}
int nret;
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size))==-1)
{
perror("falied accept");
continue;
}
memset(buff, 0, MAXDATASIZE);
recvbytes = read(client_fd, buff, MAXDATASIZE);
char str[16] = {0};
char FileName[128] = {0};
char path[128] = {0};
MyHandleBuff(buff, str, FileName, path);
if (recvbytes > 0)
{
nret = SendFileToServ(path, FileName, str);
printf("nret[%d]\n", nret);
if (1 == nret)
write(client_fd, "send file error", 15);
else if(2 == nret)
write(client_fd, "reload nginx error", 18);
else
write(client_fd, "succ", 4);
}
close(client_fd);
}
}
_________________________________________________
client:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXDATASIZE 1024
#define SERVPORT 20002
#define BACKLOG 10
int mysyslog(const char * msg)
{
FILE *fp;
if ((fp = fopen("/tmp/tmp.log", "a+")) == NULL)
{
return 0;
}
fprintf(fp, "[%s]\n", msg);
fclose(fp);
return 0;
}
static void quit_handler(int signal)
{
kill(0, SIGUSR2);
syslog( LOG_NOTICE, "apuserv quit...");
// do something exit thing ,such as close socket ,close mysql,free list
// .....
//i end
exit(0);
}
static int re_conf = 0;
static void reconf_handler(int signal)
{
re_conf=1;
syslog(LOG_NOTICE,"apuserv reload configure file .");
// ????·???????1nf == 1£???′μ?????
static int isrunning(void)
{
int fd;
int ret;
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = 0;
lock.l_start = 0;
lock.l_len = 0;
const char *lckfile = "/tmp/dstserver.lock";
fd = open(lckfile,O_WRONLY|O_CREAT);
if (fd < 0) {
syslog(LOG_ERR,"can not create lock file: %s\n",lckfile);
return 1;
}
if ((ret = fcntl(fd,F_SETLK,&lock)) < 0) {
ret = fcntl(fd,F_GETLK,&lock);
if (lock.l_type != F_UNLCK) {
close(fd);
return lock.l_pid;
}
else {
fcntl(fd,F_SETLK,&lock);
}
}
return 0;
}
int main(int argc, char **argv)
{
int sockfd,client_fd;
socklen_t sin_size;
struct sockaddr_in my_addr,remote_addr;
char buff[MAXDATASIZE];
int recvbytes;
#if 1
int pid ;
char ch ;
int ret;
int debug = 0;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, quit_handler);
syslog(LOG_NOTICE,"dstserver start....");
while ((ch = getopt(argc, argv, "dhV")) != -1) {
switch (ch) {
case 'd':
debug = 1;
break;
case 'V':
printf("Version:%s\n","1.0.0");
return 0;
case 'h':
printf(" -d use daemon mode\n");
printf(" -V show version\n");
return 0;
default:
printf(" -d use daemon mode\n");
printf(" -V show version\n");
}
}
if (debug && daemon(0,0 ) ) {
return -1;
}
if (isrunning()) {
fprintf(stderr, "dstserver is already running\n");
syslog(LOG_INFO,"dstserver is already running\n");
exit(0);
}
while (1) {
pid = fork();
if (pid < 0)
return -1;
if (pid == 0)
break;
while ((ret = waitpid(pid, NULL, 0)) != pid) {
syslog(LOG_NOTICE, "waitpid want %d, but got %d", pid, ret);
if (ret < 0)
syslog(LOG_NOTICE, "waitpid errno:%d", errno);
}
kill(0, SIGUSR2);
sleep(1);
syslog(LOG_NOTICE,"restart apuserver");
}
signal(SIGHUP, reconf_handler);
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1,SIG_IGN);
signal(SIGUSR2, SIG_DFL);
signal(SIGTERM, SIG_DFL);
#endif
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
bzero(&my_addr,sizeof(struct sockaddr_in));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
if(listen(sockfd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}
char filepath[MAXDATASIZE]= {0};
FILE *fp;
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size))==-1)
{
perror("falied accept");
continue;
}
memset(buff, 0, MAXDATASIZE);
recvbytes = read(client_fd, buff, MAXDATASIZE);
sprintf(filepath, "/etc/nginx/url_rule/%s", buff);
if ((fp = fopen(filepath, "wb")) == NULL)
{
perror("fopen");
close(client_fd);
continue;
}
write(client_fd, "sendmsg", 7);
while(read(client_fd, buff, MAXDATASIZE))
{
if (!memcmp(buff, "end", 3))
{
fclose(fp);
break;
}
else
{
fprintf(fp, "%s", buff);
write(client_fd, "goon", 4);
}
}
//system("nginx -s reload");
char *Sptr = "nginx reload succ";
char *Eptr = "nginx reload error";
int ret;
ret = system("nginx -s reload");
printf("ret[%d]\n", ret);
if (ret != 0)
{
write(client_fd, Eptr, strlen(Eptr));
}
else
{
write(client_fd, Sptr, strlen(Sptr));
}
close(client_fd);
}
}
以前写的:内容忘记了。不是很复杂你可以自己看!
linux下的 socket编程问题!
1你就打开文件,然后一个字符一个字符的读文件,然后一个字符一个字符的接收,再一个字符一个字符写入文件就行了阿
2这个问题你问的有点模糊,服务器端的编程有很多方式,也不是要每来个连接就要创建一个进程的。
第一个问题:
对,是那样的,用open打开文件,用read读取文件,在发送给对方,接收方接收到后,写入文件就可以了。不过在这个过程中最好别用字符串函数,除非你很熟悉。
第二个问题
首先你得去搞清楚什么是线程,什么是进程,fork出来的叫进程,pthread_create出来的才叫线程。服务器有很多种模型(多进程,多线程,select,epoll模型,这个我的blog上有,famdestiny.cublog.cn),不一定要用多进程。
给你写了个代码,自己先看看:
注意,在自己的目录下创建一个叫pserverb的文件,程序会把这个文件复制成test文件。你可以自己根据需要改改
server:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERV_PORT 5358
#define MAX_CONN 10
#define BUF_LEN 1024
void str_echo(FILE *fp, int sockfd){
ssize_t nread;
int file_fd;
char buf[BUF_LEN] = {0};
file_fd = open("test", O_WRONLY | O_TRUNC | O_CREAT, 0755);
while(1) {
bzero(buf, BUF_LEN);
if((nread = read(sockfd, buf, BUF_LEN)) == -1) {
if(errno == EINTR) {
continue;
}
else {
printf("readn error: %s\n", strerror(errno));
continue;
}
}
else if (nread == 0) {
break;
}
else {
printf("%s\n", buf);
write(file_fd, buf, nread);
}
}
close(file_fd);
}
void sig_chld(int sig){
pid_t pid;
int state;
while((pid = waitpid(-1, &state, WNOHANG)) > 0){
printf("child process %d exited.", pid);
}
return;
}
int main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t cliaddrlen;
pid_t childpid;
struct sockaddr_in servaddr, cliaddr;
if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
printf("socket error: %s\n", strerror(errno));
return 0;
}
bzero(&servaddr, 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)) == -1){
printf("bind error: %s\n", strerror(errno));
return 0;
}
if(listen(listenfd, MAX_CONN) == -1){
printf("listen error: %s\n", strerror(errno));
return 0;
}
signal(SIGCHLD, sig_chld);
while(1){
cliaddrlen = sizeof(cliaddr);
if((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen)) == -1){
if(errno == EINTR){
continue;
}
else{
printf("accept error: %s\n", strerror(errno));
continue;
}
}
if((childpid = fork()) == 0){
close(listenfd);
str_echo(stdin, connfd);
exit(0);
}
else if(childpid > 0){
close(connfd);
}
else{
printf("fork error!\n");
continue;
}
}
}
client:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERV_ADDR "127.0.0.1"
#define SERV_PORT 5358
#define BUF_LEN 1024
void str_cli(char *path, int sockfd)
{
char sendbuf[BUF_LEN] = {0};
int fd, n;
if((fd = open("./pserverb", O_RDONLY)) == -1){
printf("%s\n", strerror(errno));
exit(0);
}
while((n = read(fd, sendbuf, BUF_LEN)) != 0) {
if(n < 0){
printf("%s\n", strerror(errno));
exit(0);
}
write(sockfd, sendbuf, n);
bzero(sendbuf, BUF_LEN);
}
close(fd);
return;
}
int main(int argc, char **argv)
{
int fd;
struct sockaddr_in servaddr;
fd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(SERV_ADDR);
servaddr.sin_port = htons(SERV_PORT);
if (connect(fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
printf("connect error: %s\n", strerror(errno));
return 0;
}
str_cli(argv[1], fd);
return 0;
}
想问一个 关于linux下 socket编程的问题! 请进
一个线程要对应一个单独的fd,而fd2是全局变量,被所有线程公用。
注:每个fd都对应一段缓存,如果thread1读完了这段缓存之后,thread2再去读的话,是什么也读不到的。
1.把int sin_size改为socklen_t sin_size
改完即可编译通过,这个视不同的编译器而不同。
2.if(argc!=2)
{
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);
exit(1);
}
意思是如果输入的不是两个字符串,就会退出程序。看来此程序只能输两个字符串,第二个字符串必须是端口号。
3.努力!
4. 最后的 close()函数用来关闭建立的socket服务。
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) 此句建立了名为sockfd的socket服务,程序结束时要把它close掉。
》 accept函数中,第三个参数原型是 socklen_t的,这是个什么啊? 编译的时候总是 说 它和int 的转换无效! 应该怎么修改?
socklen_t 是 结构体类型的
》我想问的是,这个 服务器IP和 端口号 在程序里面是怎么体现出来的?
就是程序参数 argv
是不是 那个 if(argc!=2) 决定的啊? 也就是命令行必须 输出2个字符串
那个只决定了只能有二个参数,ip地址和端口号。
这是输入,看不懂你说的输出是什么意思。
打开窗口就行了
1、 accept函数中,第三个参数原型是 socklen_t的,这是个什么啊? 编译的时候总是 说 它和int 的转换无效! 应该怎么修改?
a.accept的函数原型为int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);最后一个参数是socklen_t类型,没记错的话,他是unsigned int类型。所以会有gcc会warning(g++则报错,g++更严格)
2、编译的时候 命令行输入的是:
./TCPServer (服务器IP) (端口号)
我想问的是,这个 服务器IP和 端口号 在程序里面是怎么体现出来的?
是不是 那个 if(argc!=2) 决定的啊? 也就是命令行必须 输出2个字符串。
如果输出 三个字符串(包括端口号) 能行么? 哪位高手帮帮我啊!
a.服务器的IP是写死在程序里的,这句,
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);INADDR_ANY表示让协议栈自己选IP地址(针对多IP的情况);端口体现在这句 server_addr.sin_port=htons(portnumber);程序要求你输入两个字符串,其中第一个为程序名,第二个为端口号。比如你编译出来的程序叫server,则命令为server 8888,就可以执行了。注意这里的argc等于几表示连程序名称在内总共有几个字符串。
4、 最后的 close()函数 作用范围不明!
因为你调用了socket函数打开了一个描述字sockfd,所以这里要把他关闭。
newfd是你accept返回的描述字,前面已经关了,这两个是不一样的。sockfd用来监听,newfd用来与建立连接的对端通讯。
另外,你露了头文件,所以warning
#include
#include
#include
#include
#include
#include
#include
#include
#define WAITBUF 10
#include
#include
int main(int argc, char *argv[])
{
int sockfd,new_fd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
socklen_t sin_size;
int portnumber;
char hello[]="Hello! Socket communication world!\n";
if(argc!=2)
{
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);
exit(1);
}
/*端口号不对,退出*/
if((portnumber=atoi(argv[1]))<0)
{
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);
exit(1);
}
/*服务器端开始建立socket描述符*/
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket error:%s\n\a",strerror(errno));
exit(1);
}
/*服务器端填充 sockaddr结构*/
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;
/*自动填充主机IP*/
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(portnumber);
/*捆绑sockfd描述符*/
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
exit(1);
}
/*监听sockfd描述符*/
if(listen(sockfd, WAITBUF)==-1)
{
fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
exit(1);
}
while(1)
{
/*服务器阻塞,直到客户程序建立连接*/
sin_size=sizeof(struct sockaddr_in);
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)
{
fprintf(stderr,"Accept error:%s\n\a",strerror(errno));
exit(1);
}
/*可以在这里加上自己的处理函数*/
fprintf(stderr,"Server get connection from %s\n",
inet_ntoa(client_addr.sin_addr));
if(send(new_fd,hello,strlen(hello),0)==-1)
{
fprintf(stderr,"Write Error:%s\n",strerror(errno));
exit(1);
}
/*这个通信已经结束*/
close(new_fd);
/*循环下一个*/
}
close(sockfd);
exit(0);
}
linux下socket编程中close()函数??
不可以,调用close后底层会四次握手,连接中断,句柄已经不可用了
只要不用close或fclose,不管把这个socket_fd值存到哪里,都可以使用。比如:
int socket_fd = socket(...);
int socket_x = socket_fd;
那么send(socket_x)和send(socket_fd)结果完全一致
你已经close了为什么还要使用它呢?如果还需要使用这个连接,就不要close等用完了,退出的时候再把它关闭。
Linux编程socket通信疑问
什么是Socket
Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解Socket接口。
Socket接口设计者......
答案就在这里:linux
socket
通信编程
----------------------Hi,地球人,我是问答机器人小S,上面的内容就是我狂拽酷炫叼炸天的答案,除了赞同,你还有别的选择吗?
Windows Socket和Linux Socket编程的区别
1)头文件windows下winsock.h/winsock2.hlinux下sys/socket.h错误处理:errno.h其他常用函数的头文件可到命令行下用man指令查询。2)初始化windows下需要用WSAStartuplinux下不需要(很方便),直接可以使用3)关闭socketwindows下closeso
SOCKET在原理上应该是一样的,只是不同系统的运行机置有些不同。
Socket 编程 windows到Linux代码移植遇到的问题
1、一些常用函数的移植
2、网络
socket相关程序从windows移植到linux下需要注意的
1)头文件
windows下winsock.h/winsock2.h
linux下sys/socket.h
错误处理:errno.h
其他常用函数的头文件可到命令行下用man指令查询。
2)初始化
windows下需要用WSAStartup
linux下不需要(很方便),直接可以使用
3)关闭socket
windows下closesocket(...)
linux下close(...)
4)类型
windows下SOCKET
在linux下为int类型
5)绑定地址的结构体
名称相同,都是struct sockaddr、struct sockaddr_in,这两者通常转换使用;
在Windows下面名称都是大写,而在Linux下为小写
常用:
Linux下:
sockaddr_in destAddr;
destAdd.sin_family=AF_INET;
destAddr.sin_port=htons(2030);
destAddr.sin_addr.s_addr=inet_addr("192.168.1.1");
Windows下:
SOCKADDR_IN destAddr;
destAddr.sin_addr.S_un.S_addr=inet_addr("192.168.1.1");
但结构体中成员的名称不同
Windows中结构体成员
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
};
下面的一些宏可以使windows下的程序移植到linux下(通过类型的重新定义,使代码具有linux和windows下的移植性)
[cpp] view plaincopy
#ifdef WIN32
typedef int socklen_t;
typedef int ssize_t;
#endif
#ifdef __LINUX__
typedef int SOCKET;
typedef unsigned char BYTE;
typedef unsigned long DWORD;
#define FALSE 0
#define SOCKET_ERROR (-1)
#endif
[cpp] view plaincopy
#ifdef WIN32
typedef int socklen_t;
typedef int ssize_t;
#endif
#ifdef __LINUX__
typedef int SOCKET;
typedef unsigned char BYTE;
typedef unsigned long DWORD;
#define FALSE 0
#define SOCKET_ERROR (-1)
#endif
6)获取错误码
windows下getlasterror()/WSAGetLastError()
linux下errno变量
7)设置非阻塞
windows下ioctlsocket()
linux下fcntl()
8)send函数最后一个参数
windows下一般设置为0
linux下最好设置为MSG_NOSIGNAL,如果不设置,在发送出错后有可 能会导致程序退出。
9)毫秒级时间获取
windows下GetTickCount()
linux下gettimeofday()
10)数据类型的一些转化
通用的:
小端到大端(网络协议使用)的转换:htonl, htons
点分十进制IP和整数之间的相互转换:inet_addr()(该函数将点分十进制转为整数),inet_aton(),inet_ntoa(),inet_pton()(linux下独有 该函数可以实现相互之间的转换)
使用到的头文件不相同,linux下用man命令查询。
另外注意:
linux下使用的套接字为伯克利套接字,因此在select()函数的使用上(第一个参数的设置)也有区别;
windows下为了与伯克利套接字匹配,第一个参数是无所谓,一般可设为0;
int maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!
3、多线程
多线程: (win)process.h --〉(linux)pthread.h
_beginthread --> pthread_create
_endthread --> pthread_exit
socket编程在windows和linux下的区别是什么?
1. 头文件
windows下winsock.h或winsock2.h
linux下netinet/in.h(大部分都在这儿),unistd.h(close函数在这儿),sys/socket.h(在in.h里已经包含了,可以省了)
2. 初始化
windows下需要用WSAStartup启动Ws2_32.lib,并且要用#pragma comment(lib,"Ws2_32")来告知编译器链接该lib。
linux下不需要
3. 关闭socket
windows下closesocket(...)
linux下close(...)
4. 类型
windows下SOCKET
linux下int
5. 获取错误码
windows下getlasterror()/WSAGetLastError()
linux下,未能成功执行的socket操作会返回-1;如果包含了errno.h,就会设置errno变量
6. 设置非阻塞
windows下ioctlsocket()
linux下fcntl(),需要头文件fcntl.h
7. send函数最后一个参数
windows下一般设置为0
linux下最好设置为MSG_NOSIGNAL,如果不设置,在发送出错后有可能会导致程序退出
8. 毫秒级时间获取
windows下GetTickCount()
linux下gettimeofday()